Jadi kita lihat bahawa dalam tiga garisan a, b, dan c, garisan b adalah satu BAR lebih perlahan daripada garisan a, dan garisan c adalah satu BAR lebih perlahan daripada garisan b.
Kita boleh menarik carta ke kiri jauh dan memerhatikan bahawa pada garis K pertama, kedua-dua nilai b dan c adalah null (na). Ini kerana apabila skrip dijalankan pada garis K pertama BAR, ia tidak wujud ketika merujuk kepada nilai sejarah satu atau dua tempoh ke hadapan, yang tidak wujud. Oleh itu, kita perlu berhati-hati ketika menulis strategi untuk memeriksa sama ada merujuk data sejarah akan menghasilkan nilai nol. Jika nilai nol digunakan dengan ceroboh, ia akan menyebabkan satu siri perbezaan pengiraan, dan mungkin juga mempengaruhi BAR masa nyata. Biasanya kita akan menggunakan fungsi terbina dalamna
, nz
untuk menilai dalam kod (sebenarnya, kita juga telah menghadapinz
, ```na`` dalam video kami sebelumnya, adakah anda ingat bab mana itu?) menangani kes nilai sifar, contohnya:
close > nz(close[1], open) // When referencing the historical value of the previous BAR of the close built-in variable, if it does not exist, the open built-in variable is used
Ini adalah cara untuk mengendalikan rujukan yang mungkin kepada nilai sifar (na).
Kita telah belajar banyak operator dalam bahasa Pine. Operator ini membentuk ungkapan melalui pelbagai kombinasi dengan operand. Jadi apakah keutamaan operasi ini ketika menilai dalam ungkapan? Sama seperti aritmatika yang kita pelajari di sekolah, perkalian dan pembahagian dikira terlebih dahulu, diikuti dengan penambahan dan pengurangan. Begitu juga dengan ungkapan dalam bahasa Pine.
Keutamaan | Pengendali |
---|---|
9 | [] |
8 | + 、- dannot dalam pengendali unari |
7 | * 、/ 、% |
6 | + 、- dalam pengendali binari |
5 | > 、< 、>= 、<= |
4 | == 、!= |
3 | and |
2 | or |
1 | ?: |
Ekspresi keutamaan tinggi dikira terlebih dahulu, dan jika keutamaan adalah sama, ia dinilai dari kiri ke kanan.()
untuk membungkus ungkapan untuk memaksa bahagian untuk dinilai terlebih dahulu.
Kita telah mempelajari konsep
Mod Pengisytiharan:
Perkara pertama yang perlu ditulis apabila mengisytiharkan pembolehubah adalah
var
.varip
.Peraturanvar
danvarip
kata kunci telah sebenarnya dikaji dalam bab kami sebelumnya padaAssignment Operators
, jadi kita tidak akan masuk ke dalam butiran di sini. jika tiada apa-apa yang ditulis untuk mod pengisytiharan pembolehubah, seperti pernyataan:i = 1
, seperti yang kita juga telah disebutkan sebelum ini, pembolehubah seperti yang diisytiharkan dan ditetapkan dijalankan pada setiap K-garis BAR.
Jenis Bahasa Pine pada FMZ tidak ketat mengenai jenis, dan umumnya boleh dihilangkan. Walau bagaimanapun, untuk serasi dengan strategi skrip pada Trading View, pembolehubah juga boleh diisytiharkan dengan jenis. Sebagai contoh:
int i = 0
float f = 1.1
Keperluan jenis pada Trading View agak ketat, dan satu ralat akan dilaporkan jika kod berikut digunakan pada Trading View:
baseLine0 = na // compile time error!
Penanda Penanda adalah nama pembolehubah. Penamaan penanda telah disebutkan dalam bab-bab sebelumnya, jadi anda boleh mengulasnya di sini:https://www.fmz.com/bbs-topic/9637#markers
Ringkasnya, mengisytiharkan pembolehubah boleh ditulis sebagai:
// [<declaration_mode>] [<type>] <marker> = value
declaration mode type marker = value
Operator tugasan digunakan di sini:=
menetapkan nilai kepada pembolehubah apabila ia diisytiharkan. Apabila menetapkan nilai boleh menjadi rentetan, nombor, ungkapan, panggilan fungsi,if
, for
, while
, atauswitch
dan struktur lain (kata kunci struktur dan penggunaan pernyataan ini akan dijelaskan secara terperinci dalam kursus seterusnya. sebenarnya, kita telah belajar mudah jika tugasan pernyataan dalam kursus sebelumnya dan anda boleh mengkaji semula mereka).
Di sini kita memberi tumpuan kepada fungsi input, yang merupakan fungsi yang akan kita gunakan dengan kerap apabila merancang dan menulis strategi.
fungsi input:
input function, parameters: defval、title、tooltip、inline、group
Fungsi input pada FMZ agak berbeza daripada pada Trading View, tetapi fungsi ini digunakan sebagai input penugasan parameter strategi.
param1 = input(10, title="name of param1", tooltip="description for param1", group="group name A")
param2 = input("close", title="name of param2", tooltip="description for param2", group="group name A")
param3 = input(color.red, title="name of param3", tooltip="description for param3", group="group name B")
param4 = input(close, title="name of param4", tooltip="description for param4", group="group name B")
param5 = input(true, title="name of param5", tooltip="description for param5", group="group name C")
ma = ta.ema(param4, param1)
plot(ma, title=param2, color=param3, overlay=param5)
Fungsi input sering digunakan untuk menetapkan nilai kepada pembolehubah semasa mengisytiharkannya. Fungsi input pada FMZ menarik kawalan untuk menetapkan parameter strategi secara automatik dalam antara muka strategi FMZ. Kawalan yang disokong pada FMZ kini termasuk kotak input numerik, kotak input teks, kotak drop-down, dan kotak semak Boolean.
Kami memperkenalkan beberapa parameter utama fungsi input:
Sebagai tambahan kepada pengisytiharan dan penugasan pembolehubah individu, terdapat juga cara untuk mengisytiharkan sekumpulan pembolehubah dan menugaskannya dalam bahasa Pine:
[Variable A, Variable B, Variable C] = function or structure, such as ```if```, ```for```, ```while``` or ```switch```
Yang paling biasa ialah apabila kita menggunakanta.macd
fungsi untuk mengira penunjuk MACD, kerana penunjuk MACD adalah penunjuk pelbagai baris, tiga set data dikira.
[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)
Kita boleh melukis carta MACD menggunakan kod di atas dengan mudah. Bukan sahaja fungsi terbina dalam boleh kembali kepada pelbagai pembolehubah, tetapi juga fungsi tersuai yang ditulis boleh kembali kepada pelbagai data.
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)
Kaedah penulisan menggunakan jika dan struktur lain sebagai tugasan pembolehubah berbilang juga serupa dengan fungsi tersuai di atas, dan anda boleh mencubanya jika anda berminat.
[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)
Sesetengah fungsi tidak boleh ditulis dalam blok kod tempatan cawangan bersyarat, terutamanya termasuk fungsi berikut:
barcolor ((), isi ((), hline ((), penunjuk ((), plot ((), plotcandle ((), plotchar ((), plotshape (()
Trading View akan mengumpul dengan ralat, FMZ tidak begitu ketat, tetapi disyorkan untuk mengikuti spesifikasi Trading View.
strategy("test", overlay=true)
if close > open
plot(close, title="close")
else
plot(open, title="open")
Contoh penjelasan:
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)
Titik utama: Ungkapan yang digunakan untuk penghakiman yang mengembalikan nilai Boolean. Perhatikan indentasi. Terdapat paling banyak satu cawangan lain. Jika semua ungkapan cawangan tidak benar dan tidak ada cawangan lain, kembali ke.
x = if close > open
close
plot(x, title="x")
Perintah suis juga merupakan perintah bercabang, yang digunakan untuk merancang laluan yang berbeza untuk dilaksanakan mengikut keadaan tertentu.
Terdapat dua bentuk suis, mari kita lihat contoh satu demi satu untuk memahami penggunaannya.
switch
dengan ungkapan - contoh penjelasan:// input.string: defval, title, options, tooltip
func = input.string("EMA", title="indicator name", tooltip="select the name of the indicator function to be used", options=["EMA", "SMA", "RMA", "WMA"])
// input.int: defval, title, options, tooltip
// param1 = input.int(10, title="period parameter")
fastPeriod = input.int(10, title="fastPeriod parameter", options=[5, 10, 20])
slowPeriod = input.int(20, title="slowPeriod parameter", options=[20, 25, 30])
data = input(close, title="data", tooltip="select the closing price, opening price, highest price...")
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)
Kita belajar fungsi input sebelum ini, di sini kita terus belajar dua fungsi yang serupa dengan input:input.string
, input.int
functions.
input.string
digunakan untuk mengembalikan rentetan, daninput.int
fungsi digunakan untuk mengembalikan nilai bilangan bulat. Dalam contoh, terdapat penggunaan baruoptions
parameter.options
parameter boleh lulus pelbagai nilai pilihan, sepertioptions=["EMA", "SMA", "RMA", "WMA"]
danoptions=[5, 10, 20]
dalam contoh (perhatikan bahawa satu adalah jenis rentetan, yang lain adalah jenis berangka). Dengan cara ini, kawalan pada antara muka strategi tidak perlu memasukkan nilai tertentu, tetapi kawalan menjadi kotak drop-down untuk memilih pilihan ini yang disediakan dalam parameter pilihan.
Nilai pembolehubah func adalah rentetan, dan pembolehubah func digunakan sebagai ungkapan untuk suis (yang boleh menjadi pembolehubah, panggilan fungsi, atau ungkapan) untuk menentukan cawangan mana dalam suis yang dilaksanakan.runtime.error("error")
fungsi akan dilaksanakan, menyebabkan strategi untuk membuang pengecualian dan berhenti.
Dalam kod ujian kami di atas, selepas baris terakhir runtime.error dalam blok kod cawangan lalai suis, kami tidak menambah kod seperti [na, na] untuk serasi dengan nilai pulangan. Masalah ini perlu dipertimbangkan di Trading View. Jika jenisnya tidak konsisten, kesilapan akan dilaporkan. Tetapi di FMZ, kerana jenisnya tidak diperlukan secara ketat, kod keserasian ini boleh dihilangkan. Oleh itu, tidak perlu mempertimbangkan keserasian jenis nilai pulangan if dan switch branch di FMZ.
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)
Tiada kesilapan akan dilaporkan pada FMZ, tetapi kesilapan akan dilaporkan pada trading view. kerana jenis yang dikembalikan oleh if branch tidak konsisten.
switch
tanpa ungkapanSeterusnya, mari kita lihat cara lain untuk menggunakanswitch
, iaitu, tanpa ekspresi.
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)
Seperti yang dapat kita lihat dari contoh kod ujian, switch akan sepadan dengan pelaksanaan blok kod tempatan yang benar pada keadaan cawangan. Secara umum, syarat cawangan yang mengikuti pernyataan switch mesti saling eksklusif. Maksudnya, ke atas dan ke bawah dalam contoh tidak boleh benar pada masa yang sama. Kerana switch hanya boleh menjalankan blok kod tempatan satu cawangan, jika anda berminat, anda boleh mengganti baris ini dalam kod:up = close > open // up = close < open
anda akan mendapati bahawa cawangan suis hanya boleh melaksanakan cawangan pertama. Di samping itu, perlu memberi perhatian untuk tidak menulis panggilan fungsi dalam cawangan suis sebanyak mungkin, fungsi tidak boleh dipanggil pada setiap BAR boleh menyebabkan beberapa masalah pengiraan data (kecuali seperti dalam contoh "switch
dengan ungkapan", cawangan pelaksanaan adalah deterministik dan tidak akan diubah semasa operasi strategi).
return value = for count = start count to final count by step length
statement // Note: There can be break and continue in the statement
statement // Note: The last statement is the return value
Perkataan for sangat mudah digunakan, gelung for akhirnya boleh mengembalikan nilai (atau pelbagai nilai, dalam bentuk [a, b, c]). Seperti pembolehubah yang diberikan kepada kedudukan
Peraturanbreak
Kata kunci yang digunakan dalam gelung for: gelung berhenti apabilabreak
Perintah dilaksanakan.
Peraturancontinue
Kata kunci yang digunakan dalam gelung for: Apabilacontinue
Perintah dijalankan, gelung akan mengabaikan kod selepascontinue
dan menjalankan pusingan seterusnya secara langsung. perintah for kembali ke nilai pulangan dari pelaksanaan terakhir gelung. dan ia kembali null jika tiada kod dijalankan.
Kemudian kita tunjukkan dengan contoh mudah:
ret = for i = 0 to 10 // We can increase the keyword by to modify the step length, FMZ does not support reverse loops such as i = 10 to 0 for now
// We can add condition settings, use continue to skip, use break to jump out
runtime.log("i:", i)
i // If this line is not written, it will return null because there is no variable to return
runtime.log("ret:", ret)
runtime.error("stop")
Peraturanfor ... in
Perkataan mempunyai dua bentuk, kita akan menggambarkan mereka dalam pseudocode berikut.
return value = for array element in array
statement // Note: There can be break and continue in the statement
statement // Note: The last statement is the return value
Return value = for [index variable, array element corresponding to index variable] in array
statement // Note: There can be break and continue in the statement
statement // Note: The last statement is the return value
Kita dapat melihat bahawa perbezaan utama antara kedua-dua bentuk adalah kandungan yang mengikuti kata kunci for, satu adalah untuk menggunakan pembolehubah sebagai pembolehubah yang merujuk kepada unsur-unsur array, yang lain adalah untuk menggunakan struktur yang mengandungi pembolehubah indeks, tuples pembolehubah unsur array sebagai rujukan.
testArray = array.from(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
for ele in testArray // Modify it to the form of [i, ele]: for [i, ele] in testArray, runtime.log("ele:", ele, ", i:", i)
runtime.log("ele:", ele)
runtime.error("stop")
Apabila ia perlu menggunakan indeks, gunakan tatabahasafor [i, ele] in testArray
.
Penggunaan untuk gelung
Kita boleh menggunakan fungsi terbina dalam yang disediakan dalam bahasa Pine untuk melengkapkan beberapa pengiraan logik gelung, sama ada ditulis dengan menggunakan struktur gelung secara langsung atau diproses menggunakan fungsi terbina dalam.
Apabila merancang dengan struktur gelung:
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)
Contoh menggunakan gelung for untuk mengira jumlah dan kemudian mengira nilai purata.
Mengira purata bergerak secara langsung menggunakan fungsi terbina dalam:
plot(ta.sma(close, length), title="ta.sma", overlay=true)
Gunakan fungsi terbina dalamta.sma
jelas, lebih mudah untuk menggunakan fungsi terbina dalam untuk mengira purata bergerak. dengan membandingkan pada carta, ia dapat dilihat bahawa hasil yang dikira adalah sama.
Kami masih menggunakan contoh di atas untuk menggambarkan.
Apabila merancang dengan struktur gelung:
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)
Untuk mengira jumlah semua elemen dalam array, kita boleh menggunakan gelung untuk memprosesnya, atau menggunakan fungsi terbina dalamarray.sum
untuk mengira.
Mengira jumlah secara langsung menggunakan fungsi terbina dalam:
length = 5
var a = array.new(length)
array.push(a, close)
if array.size(a) >= length
array.remove(a, 0)
plot(array.sum(a) / length, title="avg", overlay=true)
plot(ta.sma(close, length), title="ta.sma", overlay=true)
Kita boleh lihat data yang dikira adalah sama dengan yang dipaparkan pada carta menggunakan plot.
Jadi mengapa merancang gelung apabila kita boleh melakukan semua ini dengan fungsi terbina dalam? penggunaan gelung adalah terutamanya berdasarkan aplikasi ini 3 titik:
Peraturanwhile
Perintah menyimpan kod dalam seksyen gelung yang dijalankan sehingga keadaan penghakiman dalam struktur sementara adalah salah.
return value = while judgment condition
statement // Note: There can be break and continue in the statement
statement // Note: The last statement is the return value
Peraturan lain while adalah sama dengan yang untuk gelung. baris terakhir blok kod tempatan badan gelung adalah nilai pulangan, yang boleh mengembalikan pelbagai nilai. Melakukan gelung apabila
Kami masih akan menggunakan contoh pengiraan purata bergerak untuk demonstrasi:
length = 10
sma(data, length) =>
i = 0
sum = 0
while i < 10
sum += data[i]
i += 1
sum / length
plot(sma(close, length), title="sma", overlay=true)
plot(ta.sma(close, length), title="ta.sma", overlay=true)
Kita dapat melihat bahawa gelung sementara juga sangat mudah digunakan, dan ia juga mungkin untuk merancang beberapa logik pengiraan yang tidak boleh digantikan oleh fungsi terbina dalam, seperti mengira faktor:
counter = 5
fact = 1
ret = while counter > 0
fact := fact * counter
counter := counter - 1
fact
plot(ret, title="ret") // ret = 5 * 4 * 3 * 2 * 1
Definisi array dalam bahasa Pine adalah serupa dengan yang terdapat dalam bahasa pengaturcaraan lain. Array Pine adalah array satu dimensi. Biasanya ia digunakan untuk menyimpan satu siri data yang berterusan. Data tunggal yang disimpan dalam array dipanggil elemen array, dan jenis elemen ini boleh menjadi: bilangan bulat, titik terapung, rentetan, nilai warna, nilai boolean. Bahasa Pine pada FMZ tidak sangat ketat mengenai jenis, dan ia juga boleh menyimpan rentetan dan nombor dalam array pada masa yang sama. Oleh kerana struktur asas array juga merupakan struktur siri, jika operator sejarah digunakan untuk merujuk kepada keadaan array pada BAR sebelumnya.[]
untuk merujuk kepada elemen dalam array, kita perlu menggunakan fungsiarray.get()
danarray.set()
. Urutan indeks elemen dalam array adalah bahawa indeks elemen pertama array adalah 0, dan indeks elemen seterusnya ditingkatkan dengan 1.
Kami menerangkannya dengan kod yang mudah:
var a = array.from(0)
if bar_index == 0
runtime.log("current value a on BAR:", a, ", a on the last BAR, i.e. the value of a[1]:", a[1])
else if bar_index == 1
array.push(a, bar_index)
runtime.log("current value a on BAR:", a, ", a on the last BAR, i.e. the value of a[1]:", a[1])
else if bar_index == 2
array.push(a, bar_index)
runtime.log("current value a on BAR:", a, ", a on the last BAR, i.e. the value of a[1]:", a[1], ", a on the last second BAR, i.e. the value of a[2]:", a[2])
else if bar_index == 3
array.push(a, bar_index)
runtime.log("current value a on BAR:", a, ", a on the last BAR, i.e. the value of a[1]:", a[1], ", a on the last second BAR, i.e. the value of a[2]:", a[2], ", a on the last third BAR, i.e. the value of a[3]:", a[3])
else if bar_index == 4
// Obtain elements by index using array.get, modify elements by index using array.set
runtime.log("Before array modification:", array.get(a, 0), array.get(a, 1), array.get(a, 2), array.get(a, 3))
array.set(a, 1, 999)
runtime.log("After array modification:", array.get(a, 0), array.get(a, 1), array.get(a, 2), array.get(a, 3))
Penggunaanarray<int> a
, float[] b
untuk mengisytiharkan array atau hanya mengisytiharkan pembolehubah yang boleh diberikan array, contohnya:
array<int> a = array.new(3, bar_index)
float[] b = array.new(3, close)
c = array.from("hello", "fmz", "!")
runtime.log("a:", a)
runtime.log("b:", b)
runtime.log("c:", c)
runtime.error("stop")
Variabel array dimulakan dengan menggunakanarray.new
danarray.from
Terdapat juga banyak fungsi yang berkaitan dengan jenis yang serupa denganarray.newdalam bahasa Pine:array.new_int()
, array.new_bool()
, array.new_color()
, array.new_string()
, dan lain-lain
Kata kunci var juga berfungsi dengan mod pengisytiharan array. Array yang diisytiharkan dengan kata kunci var hanya dimulakan pada BAR pertama. Mari kita perhatikan dengan contoh:
var a = array.from(0)
b = array.from(0)
if bar_index == 1
array.push(a, bar_index)
array.push(b, bar_index)
else if bar_index == 2
array.push(a, bar_index)
array.push(b, bar_index)
else if barstate.islast
runtime.log("a:", a)
runtime.log("b:", b)
runtime.error("stop")
Ia dapat dilihat bahawa perubahan array a telah terus ditentukan dan tidak diset semula. array b dimulakan pada setiap BAR. Akhirnya, apabilabarstate.islast
adalah benar, masih ada hanya satu elemen dicetak dengan nilai 0.
Gunakan array.get untuk mendapatkan elemen di kedudukan indeks yang ditentukan dalam array, dan gunakan array.set untuk mengubah suai elemen di kedudukan indeks yang ditentukan dalam array.
Parameter pertama array.get adalah array yang akan diproses, dan parameter kedua adalah indeks yang ditentukan. Parameter pertama untuk array.set adalah array yang akan diproses, parameter kedua adalah indeks yang ditentukan, dan parameter ketiga adalah elemen yang akan ditulis.
Kami menggunakan contoh mudah berikut untuk menggambarkan:
lookbackInput = input.int(100)
FILL_COLOR = color.green
var fillColors = array.new(5)
if barstate.isfirst
array.set(fillColors, 0, color.new(FILL_COLOR, 70))
array.set(fillColors, 1, color.new(FILL_COLOR, 75))
array.set(fillColors, 2, color.new(FILL_COLOR, 80))
array.set(fillColors, 3, color.new(FILL_COLOR, 85))
array.set(fillColors, 4, color.new(FILL_COLOR, 90))
lastHiBar = - ta.highestbars(high, lookbackInput)
fillNo = math.min(lastHiBar / (lookbackInput / 5), 4)
bgcolor(array.get(fillColors, int(fillNo)), overlay=true)
plot(lastHiBar, title="lastHiBar")
plot(fillNo, title="fillNo")
Contoh ini mengisytiharkan warna asas hijau, mengisytiharkan dan mengisytiharkan array untuk menyimpan warna, dan kemudian menetapkan nilai ketelusan yang berbeza kepada warna (dengan menggunakancolor.newkadar warna dikira dengan mengira jarak BAR semasa dari nilai maksimum tinggi dalam 100 tempoh melihat kembali. semakin dekat jarak ke nilai maksimum HIGH dalam 100 kitaran melihat kembali terakhir, semakin tinggi kedudukan dan lebih gelap (transparansi yang lebih rendah) nilai warna yang sepadan. banyak strategi serupa menggunakan kaedah ini untuk mewakili tahap harga semasa dalam N tempoh melihat kembali.
Bagaimana untuk mengulangi melalui array, kita boleh menggunakan for/for in/while statement yang kita telah belajar sebelum ini.
a = array.from(1, 2, 3, 4, 5, 6)
for i = 0 to (array.size(a) == 0 ? na : array.size(a) - 1)
array.set(a, i, i)
runtime.log(a)
runtime.error("stop")
a = array.from(1, 2, 3, 4, 5, 6)
i = 0
while i < array.size(a)
array.set(a, i, i)
i += 1
runtime.log(a)
runtime.error("stop")
a = array.from(1, 2, 3, 4, 5, 6)
for [i, ele] in a
array.set(a, i, i)
runtime.log(a)
runtime.error("stop")
Ketiga-tiga kaedah traversal ini mempunyai hasil pelaksanaan yang sama.
Array boleh diisytiharkan dalam skop global skrip, atau dalam skop tempatan fungsi atau jika cawangan.
Untuk penggunaan unsur dalam array, cara berikut adalah sama. kita boleh melihat dengan contoh berikut bahawa dua set garis digambar pada carta, dua dalam setiap set, dan dua baris dalam setiap set mempunyai nilai yang sama.
a = array.new_float(1)
array.set(a, 0, close)
closeA1 = array.get(a, 0)[1]
closeB1 = close[1]
plot(closeA1, "closeA1", color.red, 6)
plot(closeB1, "closeB1", color.black, 2)
ma1 = ta.sma(array.get(a, 0), 20)
ma2 = ta.sma(close, 20)
plot(ma1, "ma1", color.aqua, 6)
plot(ma2, "ma2", color.black, 2)
array.unshift()
, array.insert()
, array.push()
.
array.remove()
, array.shift()
, array.pop()
, array.clear()
.
Kami menggunakan contoh berikut untuk menguji fungsi operasi penjumlahan dan penghapusan array ini.
a = array.from("A", "B", "C")
ret = array.unshift(a, "X")
runtime.log("array a:", a, ", ret:", ret)
ret := array.insert(a, 1, "Y")
runtime.log("array a:", a, ", ret:", ret)
ret := array.push(a, "D")
runtime.log("array a:", a, ", ret:", ret)
ret := array.remove(a, 2)
runtime.log("array a:", a, ", ret:", ret)
ret := array.shift(a)
runtime.log("array a:", a, ", ret:", ret)
ret := array.pop(a)
runtime.log("array a:", a, ", ret:", ret)
ret := array.clear(a)
runtime.log("array a:", a, ", ret:", ret)
runtime.error("stop")
Aplikasi penambahan, penghapusan: array sebagai barisan
Kita boleh membina struktur data
Antrian adalah struktur yang sering digunakan dalam bidang pengaturcaraan, ciri antrian adalah:
Unsur yang masuk barisan pertama, meninggalkan barisan pertama.
Dengan cara ini, ia memastikan bahawa data dalam barisan adalah data terkini, dan bahawa panjang barisan tidak akan berkembang tanpa batas.
Dalam contoh berikut, kita menggunakan struktur antrian untuk merakam harga setiap tik, mengira harga purata mudah alih pada tahap tik, dan kemudian membandingkannya dengan purata bergerak pada tahap garis K 1 minit.
strategy("test", overlay=true)
varip a = array.new_float(0)
var length = 10
if not barstate.ishistory
array.push(a, close)
if array.size(a) > length
array.shift(a)
sum = 0.0
for [index, ele] in a
sum += ele
avgPrice = array.size(a) == length ? sum / length : na
plot(avgPrice, title="avgPrice")
plot(ta.sma(close, length), title="ta.sma")
Perhatikan bahawa apabila mengisytiharkan array a, kita menentukan mod pengisytiharan dan menggunakan kata kuncivariant
Dengan cara ini, setiap perubahan harga akan direkodkan dalam array a.
Mengira fungsi korelasi:
array.avg()
mengira nilai purata semua elemen dalam array,array.min()
mengira unsur terkecil dalam array,array.max()
mengira unsur terkecil dalam array,array.stdev()
Mengira penyimpangan piawai semua elemen dalam array,array.sum()
Mengira penyimpangan standard semua elemen dalam array.
Fungsi yang berkaitan dengan operasi:array.concat()
untuk menggabungkan atau menyambung dua array.array.copy()
untuk menyalin array.array.join
untuk menyambung semua elemen array ke dalam rentetan.array.sort()
untuk diurutkan mengikut urutan menaik atau menurun.array.reverse()
untuk membalikkan susunan.array.slice()
untuk memotong array.array.includes()
untuk menilai unsur.array.indexof()
untuk kembali ke indeks kejadian pertama nilai yang dihantar sebagai parameter. Jika nilai tidak dijumpai, -1 akan dikembalikan.array.lastindexof()
untuk mencari kejadian terakhir nilai.
Contoh ujian fungsi yang berkaitan dengan pengiraan array:
a = array.from(3, 2, 1, 4, 5, 6, 7, 8, 9)
runtime.log("Arithmetic average of the array a:", array.avg(a))
runtime.log("The minimum element in the array a:", array.min(a))
runtime.log("The maximum element in the array a:", array.max(a))
runtime.log("Standard deviation in array a:", array.stdev(a))
runtime.log("Sum of all elements of the array a:", array.sum(a))
runtime.error("stop")
Ini adalah fungsi pengiraan array yang biasa digunakan.
Contoh fungsi yang berkaitan dengan operasi:
a = array.from(1, 2, 3, 4, 5, 6)
b = array.from(11, 2, 13, 4, 15, 6)
runtime.log("array a: ", a, ", array b: ", b)
runtime.log("array a, array b is concatenated with:", array.concat(a, b))
c = array.copy(b)
runtime.log("Copy an array b and assign it to the variable c, variable c:", c)
runtime.log("use array.join to process the array c, add the symbol + to the middle of each element, concatenating all elements results in a string:", array.join(c, "+"))
runtime.log("Sort the array b, in order from smallest to largest, using the parameter order.ascending:", array.sort(b, order.ascending)) // array.sort function modifies the original array
runtime.log("Sort the array b, in order from largest to smallest, using the parameter order.descending:", array.sort(b, order.descending)) // array.sort function modifies the original array
runtime.log("array a:", a, ", array b:", b)
array.reverse(a) // This function modifies the original array
runtime.log("reverse the order of all elements in the array a, after reversing, the array a is:", a)
runtime.log("Intercept array a, index 0~index 3, and follow the rule of left-closed and right-open interval:", array.slice(a, 0, 3))
runtime.log("Search for element 11 in array b:", array.includes(b, 11))
runtime.log("Search for element 100 in array a:", array.includes(a, 100))
runtime.log("Connect array a and array b, and search the index position of the first occurrence of element 2:", array.indexof(array.concat(a, b), 2), " , observe array.concat(a, b):", array.concat(a, b))
runtime.log("Connect array a and array b, and search the index position of the last occurrence of element 6:", array.lastindexof(array.concat(a, b), 6), " , observe array.concat(a, b):", array.concat(a, b))
runtime.error("stop")
Bahasa Pine boleh direka dengan fungsi tersuai. Secara umum, peraturan berikut digunakan untuk fungsi tersuai dalam bahasa Pine:
barcolor(), fill(), hline(), plot(), plotbar(), plotcandle()
) tidak boleh dipanggil dalam fungsi tersuai.Kami juga telah menggunakan fungsi tersuai untuk banyak kali dalam tutorial kami sebelumnya, seperti yang direka sebagai satu baris:
barIsUp() => close > open
Sama ada BAR semasa adalah garis positif apabila fungsi kembali.
Fungsi tersuai yang direka untuk berbilang baris:
sma(data, length) =>
i = 0
sum = 0
while i < 10
sum += data[i]
i += 1
sum / length
plot(sma(close, length), title="sma", overlay=true)
plot(ta.sma(close, length), title="ta.sma", overlay=true)
Kami menggunakan fungsi tersuai untuk merealisasikan fungsi pengiraan purata sma.
Di samping itu, dua contoh fungsi tersuai yang kita boleh kembali:
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)
Satu fungsi boleh mengira garis pantas, garis perlahan dan dua purata EMA.
Fungsi terbina dalam boleh dengan mudah dijumpai dalamDokumen skrip FMZ PINE.
Klasifikasi fungsi terbina dalam bahasa Pine:
str.
series.color.
series.input.
series.ta.
series.plot.
series.array.
series.strategy.
series.math.
series.request.
fungsi siri, fungsi pengendalian jenis, dan lain-lain)Peraturanstrategy.
siri fungsi adalah fungsi yang sering kita gunakan dalam reka bentuk strategi, dan fungsi ini berkaitan rapat dengan pelaksanaan operasi perdagangan apabila strategi dijalankan secara khusus.
strategy.entry
strategy.entry
fungsi adalah fungsi yang lebih penting apabila kita menulis strategi untuk meletakkan pesanan, beberapa parameter penting untuk fungsi adalah:id
, direction
, qty
, when
, dan lain-lain
Parameter:
id
: Ini boleh difahami sebagai memberi nama kepada kedudukan dagangan untuk rujukan. ID ini boleh dirujuk untuk membatalkan, mengubahsuai pesanan dan menutup kedudukan.direction
: Jika arah pesanan adalah panjang (beli), masukkan pembolehubah terbina dalamstrategy.long
, dan jika anda mahu pergi pendek (menjual), lulus dalam pembolehubahstrategy.short
.qty
: Tentukan jumlah pesanan yang akan diletakkan, jika parameter ini tidak diteruskan, jumlah pesanan lalai akan digunakan.when
: Keadaan pelaksanaan, anda boleh menentukan parameter ini untuk mengawal sama ada operasi pesanan semasa ini dicetuskan atau tidak.limit
: Tentukan harga had pesanan.stop
: Harga Stop Loss.Perincian pelaksanaan khususstrategy.entry
fungsi dikawal oleh tetapan parameter apabilastrategy
fungsi dipanggil, dan ia juga boleh dikawal oleh [
Kami memberi tumpuan kepadapyramiding
, default_qty_value
parameter dalamstrategy
Kami menggunakan kod berikut untuk ujian:
/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
strategy(title = "open long example", pyramiding = 3, default_qty_value=0.1, overlay=true)
ema10 = ta.ema(close, 10)
findOrderIdx(idx) =>
if strategy.opentrades == 0
false
else
ret = false
for i = 0 to strategy.opentrades - 1
if strategy.opentrades.entry_id(i) == idx
ret := true
break
ret
if not findOrderIdx("long1")
strategy.entry("long1", strategy.long)
if not findOrderIdx("long2")
strategy.entry("long2", strategy.long, 0.2, when = close > ema10)
if not findOrderIdx("long3")
strategy.entry("long3", strategy.long, 0.2, limit = low[1])
strategy.entry("long3", strategy.long, 0.3, limit = low[1])
if not findOrderIdx("long4")
strategy.entry("long4", strategy.long, 0.2)
plot(ema10, title="ema10", color=color.red)
Bahagian di awal kod/* backtest... */
adalah tetapan backtest, yang digunakan untuk merakam masa tetapan backtest dan maklumat lain pada masa itu untuk debugging, bukan kod permulaan.
Dalam kod:strategy(title = "open long example", pyramiding = 3, default_qty_value=0.1, overlay=true)
, apabila kita menentukanpyramiding
parameter sebagai 3, kita menetapkan bilangan maksimum perdagangan dalam arah yang sama kepada 3.strategy.entry
Operasi perintah dalam contoh tidak dilaksanakan.default_qty_value
parameter untuk menjadi 0.1, inistrategy.entry
operasi dengan IDlong1
mempunyai saiz pesanan lalai 0.1.strategy.entry
panggilan fungsi apabila kita menentukandirection
sebagaistrategy.long
, jadi pesanan ujian backtest adalah semua pesanan beli.
Perhatikan bahawa operasi pesananstrategy.entry("long3", ...
dalam kod dipanggil dua kali, untuk ID yang sama:long3
, yang pertamastrategy.entry
operasi pesanan tidak diisi, dan panggilan kedua kepadastrategy.entry
Satu lagi kes, contohnya, jika urutan pertama dengan ID strategy.entry
fungsi untuk meletakkan pesanan mengikut ID
strategy.close
Peraturanstrategy.close
Fungsi digunakan untuk menutup kedudukan masuk dengan ID pengenalan yang ditetapkan. Parameter utama adalah:id
, when
, qty
, qty_percent
.
Parameter:
id
: ID kemasukan yang perlu ditutup adalah ID yang kita tentukan apabila kita membuka kedudukan menggunakan fungsi pesanan kemasukan, sepertistrategy.entry
.when
: Syarat pelaksanaan.qty
: Jumlah kedudukan yang ditutup.qty_percent
: Peratusan kedudukan tertutup.Mari kita membiasakan diri dengan butiran penggunaan fungsi ini melalui contoh:
Perkhidmatan/*backtest ... */
dalam kod adalah maklumat konfigurasi untukFMZ.COMbacktest laman web antarabangsa, anda boleh memadamkannya dan menetapkan pasaran, pelbagai, julat masa dan maklumat lain yang anda perlukan untuk menguji.
/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
strategy("close Demo", pyramiding=3)
var enableStop = false
if enableStop
runtime.error("stop")
strategy.entry("long1", strategy.long, 0.2)
if strategy.opentrades >= 3
strategy.close("long1") // Multiple entry orders, no qty parameters specified, close all
// strategy.close() // Without specifying the id parameter, the current position will be closed
// strategy.close("long2") // If a non-existent id is specified then nothing is done
// strategy.close("long1", qty=0.15) // Specify qty parameters to close a position
// strategy.close("long1", qty_percent=50) // qty_percent is set to 50 to close 50% of the positions marked by long1
// strategy.close("long1", qty_percent=80, when=close<open) // Specify the parameter when, change it to close>open and it won't trigger
enableStop := true
Strategi ujian menunjukkan tiga entri panjang berturut-turut dengan ID entri strategy.close
fungsi untuk menetapkan hasil yang berbeza dari backtest apabila menutup kedudukan.strategy.close
fungsi ini tidak mempunyai parameter untuk menentukan harga pesanan untuk menutup kedudukan, fungsi ini digunakan terutamanya untuk menutup kedudukan dengan segera pada harga pasaran semasa.
strategy.close_all
Fungsistrategy.close_all
digunakan untuk menutup semua kedudukan semasa, kerana kedudukan skrip bahasa Pine hanya boleh mempunyai arah, iaitu, jika terdapat isyarat yang dicetuskan dalam arah yang bertentangan dengan kedudukan semasa akan menutup kedudukan semasa dan kemudian membukanya mengikut isyarat pencetus.strategy.close_all
akan menutup semua kedudukan dalam arah semasa apabila ia dipanggil.strategy.close_all
Fungsi adalah:when
.
Parameter:
when
: Syarat pelaksanaan.Mari kita gunakan contoh untuk memerhatikan:
/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
strategy("closeAll Demo")
var enableStop = false
if enableStop
runtime.error("stop")
strategy.entry("long", strategy.long, 0.2, when=strategy.position_size==0 and close>open)
strategy.entry("short", strategy.short, 0.3, when=strategy.position_size>0 and close<open)
if strategy.position_size < 0
strategy.close_all()
enableStop := true
Kod ujian bermula dengan nombor kedudukan 0 (iaitustrategy.position_size==0
adalah benar), jadi apabila syarat yang ditetapkan oleh apabila parameter dipenuhi, hanyastrategy.entry
fungsi kemasukan dengan ID strategy.position_size
adalah lebih besar daripada 0, maka fungsi kemasukan dengan ID strategy.position_size < 0
, iaitu apabila memegang kedudukan pendek, semua kedudukan dalam arah memegang semasa akan ditutup.enableStop := true
. Hentikan pelaksanaan strategi supaya log boleh diperhatikan.
Ia boleh didapati bahawa fungsistrategy.close_all
mempunyai tiada parameter untuk menentukan harga penutupan pesanan, fungsi ini digunakan terutamanya untuk segera menutup kedudukan pada harga pasaran semasa.
strategy.exit
Peraturanstrategy.exit
fungsi digunakan untuk menutup kedudukan kemasukan.strategy.close
danstrategy.close_all
fungsi menutup kedudukan dengan serta-merta pada harga pasaran semasa.strategy.exit
fungsi akan menutup kedudukan mengikut tetapan parameter.
Parameter:
id
: ID pengiktirafan pesanan untuk perintah keadaan penutupan semasa.from_entry
: Digunakan untuk menentukan ID kemasukan kedudukan yang akan ditutup.qty
: Jumlah kedudukan yang ditutup.qty_percent
: Peratusan kedudukan tertutup, julat: 0 ~ 100.profit
: Sasaran keuntungan, dinyatakan dalam mata.loss
: Sasaran Stop Loss, dinyatakan dalam mata.limit
: Sasaran keuntungan, ditentukan oleh harga.stop
: Sasaran Stop Loss, ditentukan oleh harga.when
: Syarat pelaksanaan.Gunakan strategi ujian untuk memahami penggunaan parameter.
/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
args: [["RunMode",1,358374],["ZPrecision",0,358374]]
*/
strategy("strategy.exit Demo", pyramiding=3)
varip isExit = false
findOrderIdx(idx) =>
ret = -1
if strategy.opentrades == 0
ret
else
for i = 0 to strategy.opentrades - 1
if strategy.opentrades.entry_id(i) == idx
ret := i
break
ret
strategy.entry("long1", strategy.long, 0.1, limit=1, when=findOrderIdx("long1") < 0)
strategy.entry("long2", strategy.long, 0.2, when=findOrderIdx("long2") < 0)
strategy.entry("long3", strategy.long, 0.3, when=findOrderIdx("long3") < 0)
if not isExit and strategy.opentrades > 0
// strategy.exit("exitAll") // If only one id parameter is specified, the exit order is invalid, and the parameters profit, limit, loss, stop and other exit conditions also need to be set at least one, otherwise it is also invalid
strategy.exit("exit1", "long1", profit=50) // Since the long1 entry order is not filled, the exit order with ID exit1 is also on hold until the corresponding entry order is filled before exit1 is placed
strategy.exit("exit2", "long2", qty=0.1, profit=100) // Specify the parameter qty to close 0.1 positions in the position with ID long2
strategy.exit("exit3", "long3", qty_percent=50, limit=strategy.opentrades.entry_price(findOrderIdx("long3")) + 1000) // Specify the parameter qty_percent to close 50% of the positions in the position with ID long3
isExit := true
if bar_index == 0
runtime.log("The price per point:", syminfo.mintick) // The price per point is related to the "Pricing Currency Precision" parameter setting on the Pine language template parameters
Kami menggunakan model harga masa nyata untuk backtest, strategi ujian bermula dengan 3 operasi kemasukan (strategy.entry
fungsi), danlong1
ditetapkan dengan sengaja denganlimit
parameter dengan harga pesanan menunggu 1, supaya ia tidak boleh diisi. kemudian menguji fungsi keluar bersyaratstrategy.exit
Kami menggunakan strategy.exit
fungsi juga mempunyai parameter trailing berhenti yang lebih kompleks:trail_price
, trail_points
, trail_offset
juga boleh diuji dalam contoh ini untuk belajar penggunaan mereka.
strategy.cancel
Peraturanstrategy.cancel
fungsi digunakan untuk membatalkan / menghentikan semua pesanan yang belum selesai.strategy.order
, strategy.entry
, strategy.exit
boleh menjana ID kemasukan. Parameter utama fungsi ini adalah:id
, when
.
Parameter:
id
: ID kemasukan akan dibatalkan.when
: Syarat pelaksanaan.Fungsi ini mudah difahami, dan ia digunakan untuk membatalkan pesanan masuk yang tidak diisi.
/*backtest
start: 2022-07-03 00:00:00
end: 2022-07-09 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"BTC_USDT"}]
*/
strategy("strategy.cancel Demo", pyramiding=3)
var isStop = false
if isStop
runtime.error("stop")
strategy.entry("long1", strategy.long, 0.1, limit=1)
strategy.entry("long2", strategy.long, 0.2, limit=2)
strategy.entry("long3", strategy.long, 0