PINE Bahasa Tutorial Pengantar FMZ Quant

Penulis:Lydia, Dibuat: 2022-09-23 15:23:34, Diperbarui: 2024-02-27 16:47:41

Jadi kita lihat bahwa pada tiga garis a, b, dan c, garis b adalah satu BAR lebih lambat dari garis a, dan garis c adalah satu BAR lebih lambat dari garis b.

Kita dapat menarik grafik ke kiri jauh dan mengamati bahwa pada garis K pertama, kedua nilai b dan c adalah nol (na). Ini karena ketika skrip dijalankan pada garis K pertama BAR, tidak ada ketika merujuk pada nilai historis satu atau dua periode ke depan, yang tidak ada. Oleh karena itu, kita perlu berhati-hati ketika menulis strategi untuk memeriksa apakah referensi data historis akan menghasilkan nilai nol. Jika nilai nol digunakan dengan ceroboh, itu akan menyebabkan serangkaian perbedaan perhitungan, dan bahkan dapat mempengaruhi BAR real-time. Biasanya kita akan menggunakan fungsi built-inna, nzuntuk menilai dalam kode (sebenarnya, kita juga telah menemukannz, ```na `` dalam video kami sebelumnya, apakah Anda ingat bab mana itu?) menangani kasus nilai nol, misalnya:

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 menangani kemungkinan referensi ke nilai nol (na).

Prioritas Operator

Kita telah belajar banyak operator dalam bahasa Pine. Operator ini membentuk ekspresi melalui berbagai kombinasi dengan operand. Jadi apa prioritas operasi ini ketika mengevaluasi dalam ekspresi? Sama seperti aritmatika yang kita pelajari di sekolah, perkalian dan pembagian dihitung terlebih dahulu, diikuti dengan penjumlahan dan pengurangan. Hal yang sama berlaku untuk ekspresi dalam bahasa Pine.

Prioritas Operator
9 []
8 +-dannotdalam operator unary
7 */%
6 +-dalam operator biner
5 ><>=<=
4 ==!=
3 and
2 or
1 ?:

Ekspresi prioritas tinggi dihitung terlebih dahulu, dan jika prioritasnya sama, dievaluasi dari kiri ke kanan.()untuk membungkus ekspresi untuk memaksa bagian yang akan dievaluasi terlebih dahulu.

Variabel

Deklarasi Variabel

Kita sudah mempelajari konsep marker sebelumnya, yang digunakan sebagai nama variabel, yaitu, variabel adalah penanda yang memegang nilai. jadi bagaimana kita mendeklarasikan variabel? apa aturan untuk mendeklarasikan variabel?

  • Mode Deklarasi: Hal pertama yang harus ditulis saat mendeklarasikan variabel adalah declaration mode. Ada tiga mode deklarasi untuk variabel:

    1. Gunakan kata kuncivar.
    2. Gunakan kata kuncivarip.
    3. Jangan menulis apa-apa.

    Peraturanvardanvaripkata kunci telah benar-benar dipelajari dalam bab kami sebelumnya padaAssignment OperatorsJika tidak ada yang ditulis untuk mode deklarasi variabel, seperti pernyataan:i = 1, seperti yang telah kami sebutkan sebelumnya, variabel tersebut dinyatakan dan ditugaskan dijalankan pada setiap K-line BAR.

  • Jenis Bahasa Pine pada FMZ tidak ketat tentang jenis, dan umumnya dapat dihilangkan. Namun, untuk kompatibel dengan strategi skrip pada Trading View, variabel juga dapat dinyatakan dengan jenis.

    int i = 0 
    float f = 1.1
    

    Persyaratan tipe pada Trading View cukup ketat, dan kesalahan akan dilaporkan jika kode berikut digunakan pada Trading View:

    baseLine0 = na          // compile time error!
    
  • Penanda Penanda adalah nama variabel. Penamaan penanda telah disebutkan dalam bab-bab sebelumnya, sehingga Anda dapat meninjau di sini:https://www.fmz.com/bbs-topic/9637#markers

Singkatnya, mendeklarasikan variabel dapat ditulis sebagai:

// [<declaration_mode>] [<type>] <marker> = value 
   declaration mode             type     marker      = value

Operator penugasan digunakan di sini:=menugaskan nilai untuk variabel ketika dinyatakan. Saat menugaskan nilai dapat menjadi string, angka, ekspresi, panggilan fungsi,if, for, while, atauswitchdan struktur lainnya (kata kunci struktural dan penggunaan pernyataan ini akan dijelaskan secara rinci dalam kursus berikutnya.

Di sini kita fokus pada fungsi input, yang merupakan fungsi yang akan kita gunakan sering ketika merancang dan menulis strategi.

Fungsi input:

input function, parameters: defval、title、tooltip、inline、group

Fungsi input pada FMZ agak berbeda dari 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 pada variabel saat mendeklarasinya. Fungsi input pada FMZ menarik kontrol untuk mengatur parameter strategi secara otomatis di antarmuka strategi FMZ. Kontrol yang didukung pada FMZ saat ini termasuk kotak input numerik, kotak input teks, kotak drop-down, dan kotak centang Boolean. Dan Anda dapat mengatur pengelompokan parameter strategi, mengatur pesan teks prompt parameter dan fungsi lainnya.

img

Kami memperkenalkan beberapa parameter utama dari fungsi input:

  • defval: Nilai default untuk opsi parameter strategi yang ditetapkan oleh fungsi input, mendukung variabel built-in bahasa Pine, nilai numerik, dan string.
  • Title: Nama parameter dari strategi yang ditampilkan pada antarmuka strategi selama live trading/backtesting.
  • Tip alat: Informasi tip alat untuk parameter strategi, ketika mouse menggeser parameter strategi, informasi teks pengaturan parameter akan ditampilkan.
  • kelompok: Nama kelompok parameter strategi, yang dapat digunakan untuk parameter strategi.

Selain deklarasi dan penugasan variabel individu, ada juga cara untuk mendeklarasikan sekelompok variabel dan menugaskannya dalam bahasa Pine:

[Variable A, Variable B, Variable C] = function or structure, such as ```if```, ```for```, ```while``` or ```switch```

Yang paling umum adalah ketika kita menggunakanta.macdfungsi untuk menghitung indikator MACD, karena indikator MACD adalah indikator multi-line, tiga set data dihitung.

[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 dapat menggambar grafik MACD menggunakan kode di atas dengan mudah. Tidak hanya fungsi built-in dapat kembali ke beberapa variabel, tetapi juga fungsi kustom tertulis dapat kembali ke beberapa 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)

Metode menulis menggunakan if dan struktur lain sebagai penugasan variabel ganda juga mirip dengan fungsi kustom di atas, dan Anda dapat mencobanya jika Anda tertarik.

[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)

Struktur Kondisi

Beberapa fungsi tidak dapat ditulis dalam blok kode lokal dari cabang bersyarat, terutama termasuk fungsi berikut:

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

Trading View akan mengkompilasi dengan kesalahan, FMZ tidak begitu membatasi, tetapi disarankan untuk mengikuti spesifikasi Trading View.

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

if pernyataan

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)

Poin penting: Ekspresi yang digunakan untuk penilaian yang mengembalikan nilai Boolean. Perhatikan indentasi. Ada paling banyak satu cabang lain. Jika semua ekspresi cabang tidak benar dan tidak ada cabang lain, kembali ke na.

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

Pernyataan switch

Pernyataan switch juga merupakan pernyataan terstruktur cabang, yang digunakan untuk merancang jalur yang berbeda untuk dieksekusi sesuai dengan kondisi tertentu.

  1. Pernyataan switch, seperti pernyataan if, juga dapat mengembalikan nilai.
  2. Tidak seperti pernyataan switch dalam bahasa lain, ketika konstruksi switch dieksekusi, hanya blok lokal dari kodenya yang dieksekusi, sehingga pernyataan break tidak perlu (yaitu, tidak perlu menulis kata kunci seperti break).
  3. Setiap cabang switch dapat menulis blok kode lokal, baris terakhir dari blok kode lokal ini adalah nilai pengembalian (itu bisa menjadi tuple nilai).
  4. Ekspresi dalam struktur switch menentukan posisi dapat menulis string, variabel, ekspresi atau panggilan fungsi.
  5. switch memungkinkan menentukan nilai pengembalian yang bertindak sebagai nilai default yang akan digunakan ketika tidak ada kasus lain dalam struktur untuk dijalankan.

Ada dua bentuk switch, mari kita lihat contohnya satu per satu untuk memahami penggunaannya.

  1. Aswitchdengan ekspresi - 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 sebelumnya, di sini kita terus belajar dua fungsi yang mirip dengan input:input.string, input.int functions. input.stringdigunakan untuk mengembalikan string, daninput.intfungsi digunakan untuk mengembalikan nilai bilangan bulat. Dalam contoh, ada penggunaan baru darioptionsparameter.optionsparameter dapat dilewati array dari nilai opsional, sepertioptions=["EMA", "SMA", "RMA", "WMA"]danoptions=[5, 10, 20]Dengan cara ini, kontrol pada antarmuka strategi tidak perlu memasukkan nilai tertentu, tetapi kontrol menjadi kotak drop-down untuk memilih opsi yang disediakan dalam parameter opsi.

Nilai dari variabel func adalah string, dan variabel func digunakan sebagai ekspresi untuk switch (yang bisa menjadi variabel, panggilan fungsi, atau ekspresi) untuk menentukan cabang mana di switch yang dieksekusi.runtime.error("error")fungsi akan dieksekusi, menyebabkan strategi untuk melemparkan pengecualian dan berhenti.

Dalam kode uji kami di atas, setelah baris terakhir runtime.error di blok kode cabang default switch, kami tidak menambahkan kode seperti [na, na] untuk kompatibel dengan nilai return. Masalah ini perlu dipertimbangkan di Trading View. Jika tipe tidak konsisten, kesalahan akan dilaporkan. Tetapi di FMZ, karena tipe tidak benar-benar diperlukan, kode kompatibilitas ini dapat dihilangkan. Oleh karena itu, tidak perlu mempertimbangkan kompatibilitas tipe dari nilai return if dan switch branches 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)

Tidak ada kesalahan yang akan dilaporkan pada FMZ, tetapi kesalahan akan dilaporkan pada trading view. Karena tipe yang dikembalikan oleh if branch tidak konsisten.

  1. switchtanpa ekspresi

Selanjutnya, mari kita lihat cara lain untuk menggunakanswitch, yaitu, 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 kode uji, switch akan sesuai dengan eksekusi blok kode lokal yang benar pada kondisi cabang. Secara umum, kondisi cabang setelah pernyataan switch harus saling eksklusif. Artinya, atas dan bawah dalam contoh tidak dapat benar pada saat yang sama. Karena switch hanya dapat mengeksekusi blok kode lokal dari satu cabang, jika Anda tertarik, Anda dapat mengganti baris ini dalam kode:up = close > open // up = close < openAnda akan menemukan bahwa switch branch hanya dapat mengeksekusi branch pertama. Selain itu perlu untuk memperhatikan untuk tidak menulis panggilan fungsi di branch switch sebanyak mungkin, fungsi tidak dapat dipanggil pada setiap BAR dapat menyebabkan beberapa masalah perhitungan data (kecuali seperti dalam contoh "switchdengan ekspresi", cabang eksekusi adalah deterministik dan tidak akan diubah selama operasi strategi).

Struktur lingkaran

untuk pernyataan

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

Pernyataan for sangat sederhana untuk digunakan, loop for akhirnya dapat mengembalikan nilai (atau beberapa nilai, dalam bentuk [a, b, c]). Seperti variabel yang ditugaskan ke posisi return value dalam pseudocode di atas. Pernyataan for diikuti oleh variabel count yang digunakan untuk mengontrol jumlah loop, merujuk pada nilai lain, dll. Variabel count ditugaskan ke count awal sebelum loop dimulai, kemudian meningkat sesuai dengan pengaturan step length, dan loop berhenti ketika variabel count lebih besar dari final count.

Peraturanbreakkata kunci yang digunakan dalam loop for: loop berhenti ketikabreakpernyataan dieksekusi. PeraturancontinueKata kunci yang digunakan dalam loop for:continuepernyataan dijalankan, loop akan mengabaikan kode setelahcontinuedan mengeksekusi putaran berikutnya dari loop secara langsung. pernyataan for kembali ke nilai kembali dari eksekusi terakhir loop. dan kembali null jika tidak ada kode yang dijalankan.

Kemudian kita menunjukkan dengan contoh sederhana:

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")

untuk... dalam pernyataan

Peraturanfor ... inpernyataan memiliki 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 bahwa perbedaan utama antara kedua bentuk adalah konten yang mengikuti kata kunci for, satu adalah menggunakan variabel sebagai variabel yang mengacu pada elemen array, yang lain adalah menggunakan struktur yang berisi variabel indeks, tuples variabel elemen array sebagai referensi. Untuk aturan nilai return lainnya, seperti menggunakan break, continue, dll, konsisten dengan untuk loop.

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")

Ketika perlu menggunakan indeks, gunakan tata bahasafor [i, ele] in testArray.

Aplikasi untuk loop

Kita dapat menggunakan fungsi built-in yang disediakan dalam bahasa Pine untuk menyelesaikan beberapa perhitungan logika loop, baik ditulis dengan menggunakan struktur loop secara langsung atau diproses dengan menggunakan fungsi built-in.

  1. Menghitung nilai rata-rata

Saat merancang dengan struktur lingkaran:

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 loop for untuk menghitung jumlah dan kemudian menghitung nilai rata-rata.

Menghitung rata-rata bergerak langsung menggunakan fungsi built-in:

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

Gunakan fungsi built-inta.smadengan menggunakan indikator rata-rata bergerak secara langsung. jelas, lebih sederhana untuk menggunakan fungsi built-in untuk menghitung rata-rata bergerak. dengan membandingkan pada grafik, dapat dilihat bahwa hasil yang dihitung persis sama.

  1. Ringkasan

Kami masih menggunakan contoh di atas untuk menggambarkan.

Saat merancang dengan struktur lingkaran:

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 menghitung jumlah semua elemen dalam array, kita dapat menggunakan loop untuk memprosesnya, atau menggunakan fungsi built-inarray.sumuntuk menghitung. Menghitung jumlah langsung menggunakan fungsi built-in:

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 dapat melihat data yang dihitung adalah persis sama dengan yang ditampilkan pada grafik menggunakan plot.

Jadi mengapa mendesain loop ketika kita bisa melakukan semua ini dengan fungsi built-in? penggunaan loop terutama didasarkan pada penerapan 3 poin ini:

  1. Untuk beberapa operasi dan perhitungan untuk array.
  2. Untuk meninjau sejarah, misalnya, untuk mencari tahu berapa banyak titik tertinggi masa lalu yang lebih tinggi dari titik tertinggi BAR saat ini.
  3. Ketika bahasa Pine built-in fungsi tidak dapat menyelesaikan perhitungan untuk BARs masa lalu.

sementara statemnet

Peraturanwhilepernyataan menjaga kode dalam bagian loop yang dijalankan sampai kondisi penilaian dalam while struktur adalah false.

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

Aturan lain while mirip dengan yang untuk loop. baris terakhir dari blok kode lokal dari tubuh loop adalah nilai return, yang dapat mengembalikan beberapa nilai. Mengeksekusi loop ketika loop condition benar, dan menghentikan loop ketika kondisi itu salah. break dan terus pernyataan juga dapat digunakan dalam tubuh loop.

Kita masih akan menggunakan contoh perhitungan rata-rata 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 bahwa loop sementara juga sangat sederhana untuk digunakan, dan juga mungkin untuk merancang beberapa logika perhitungan yang tidak dapat digantikan oleh fungsi built-in, seperti menghitung faktorial:

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

Array

Definisi array dalam bahasa Pine mirip dengan bahasa pemrograman lainnya. Array Pine adalah array satu dimensi. Biasanya digunakan untuk menyimpan serangkaian data berkelanjutan. Data tunggal yang disimpan dalam array disebut elemen array, dan jenis elemen ini dapat: integer, floating point, string, nilai warna, nilai boolean. Bahasa Pine pada FMZ tidak terlalu ketat tentang jenis, dan bahkan dapat menyimpan string dan angka dalam array pada saat yang sama. Karena struktur dasar array juga merupakan struktur seri, jika operator historis digunakan untuk merujuk pada keadaan array pada BAR sebelumnya.[]untuk merujuk pada elemen dalam array, kita perlu menggunakan fungsiarray.get()danarray.set()Urutan indeks elemen dalam array adalah bahwa indeks elemen pertama array adalah 0, dan indeks elemen berikutnya ditingkatkan dengan 1.

Kami mengilustrasikannya dengan kode sederhana:

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))

Deklarasikan array

Penggunaanarray<int> a, float[] buntuk mendeklarasikan array atau hanya mendeklarasikan variabel yang dapat ditugaskan array, misalnya:

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 diinisialisasi dengan menggunakanarray.newdanarray.fromAda juga banyak fungsi yang berhubungan dengan jenis yang mirip denganarray.newdalam bahasa Pine:array.new_int(), array.new_bool(), array.new_color(), array.new_string(), dll.

Kata kunci var juga bekerja dengan mode deklarasi array. Array yang dinyatakan dengan kata kunci var hanya diinisialisasi pada BAR pertama. Mari kita amati 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")

Kita dapat melihat bahwa perubahan array a telah terus ditentukan dan belum diatur kembali. array b diinisialisasi pada setiap BAR. Akhirnya, ketikabarstate.islastadalah benar, masih ada hanya satu elemen dicetak dengan nilai 0.

Membaca dan menulis elemen dalam array

Gunakan array.get untuk mendapatkan elemen di posisi indeks yang ditentukan dalam array, dan gunakan array.set untuk memodifikasi elemen di posisi indeks yang ditentukan dalam array.

Parameter pertama array.get adalah array yang akan diproses, dan parameter kedua adalah indeks yang ditentukan. Parameter pertama array.set adalah array yang akan diproses, parameter kedua adalah indeks yang ditentukan, dan parameter ketiga adalah elemen yang akan ditulis.

Kami menggunakan contoh sederhana 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 menginisialisasi warna dasar hijau, menyatakan dan menginisialisasi array untuk menyimpan warna, dan kemudian menetapkan nilai transparansi yang berbeda untuk warna (dengan menggunakancolor.newTingkat warna dihitung dengan menghitung jarak BAR saat ini dari nilai maksimum tinggi dalam 100 periode lookback. Semakin dekat jarak ke nilai maksimum HIGH dalam 100 siklus lookback terakhir, semakin tinggi peringkat dan semakin gelap (transparansi lebih rendah) nilai warna yang sesuai. Banyak strategi serupa menggunakan metode ini untuk mewakili tingkat harga saat ini dalam N periode lookback.

Iterasi melalui elemen array

Cara mengulangi melalui array, kita bisa menggunakan for/for in/while statement yang kita pelajari sebelumnya.

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 metode traversal ini memiliki hasil eksekusi yang sama.

Array dapat dinyatakan dalam ruang lingkup global skrip, atau dalam ruang lingkup lokal fungsi atau jika cabang.

Referensi data historis

Untuk penggunaan elemen dalam array, cara berikut ini setara. kita dapat melihat dengan contoh berikut bahwa dua set garis digambar pada bagan, dua di setiap set, dan dua garis di setiap set memiliki nilai yang sama persis.

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)

Fungsi untuk menambahkan dan menghapus array

  1. Fungsi yang terkait dengan operasi penjumlahan array:

array.unshift(), array.insert(), array.push().

  1. Fungsi yang berkaitan dengan penghapusan array:

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 antrian

Kita dapat membangun struktur data queue dengan menggunakan array dan beberapa fungsi penambahan dan penghapusan array. Queues dapat digunakan untuk menghitung moving average dari harga tik. Seseorang mungkin bertanya, Mengapa kita harus membangun struktur queue?

Antrian adalah struktur yang sering digunakan dalam bidang pemrograman, karakteristik antrian adalah:

Elemen yang masuk ke antrian pertama, meninggalkan antrian pertama.

Dengan cara ini, ia memastikan bahwa data dalam antrian adalah data terbaru, dan bahwa panjang antrian tidak akan berkembang tanpa batas.

Dalam contoh berikut, kita menggunakan struktur antrian untuk mencatat harga setiap tik, menghitung harga rata-rata bergerak pada tingkat tik, dan kemudian membandingkannya dengan rata-rata bergerak pada tingkat garis K 1 menit.

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 bahwa ketika mendeklarasikan array a, kita menentukan mode deklarasi dan menggunakan kata kuncivariantDengan cara ini, setiap perubahan harga akan dicatat dalam array a.

Fungsi perhitungan dan operasi array yang umum digunakan

Menghitung fungsi korelasi:

array.avg()menghitung nilai rata-rata dari semua elemen dalam array,array.min()menghitung elemen terkecil dalam array,array.max()menghitung elemen terkecil dalam array,array.stdev()menghitung standar deviasi dari semua elemen dalam array,array.sum()menghitung standar deviasi dari semua elemen dalam array.

Fungsi yang berhubungan dengan operasi:array.concat()untuk menggabungkan atau konkaten dua array.array.copy()untuk menyalin array.array.joinuntuk mengkonkaten semua elemen array ke dalam string.array.sort()untuk menyortir dengan naik atau turun urutan.array.reverse()untuk membalikkan array.array.slice()untuk memotong array.array.includes()untuk menilai elemen.array.indexof()untuk kembali ke indeks kejadian pertama dari nilai yang diteruskan sebagai parameter. Jika nilai tidak ditemukan, -1 akan dikembalikan.array.lastindexof()untuk menemukan kejadian terakhir dari nilai.

Contoh pengujian fungsi terkait perhitungan 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 perhitungan array yang umum digunakan.

Contoh fungsi yang terkait 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")

Fungsi

Fungsi Khusus

Bahasa Pine dapat dirancang dengan fungsi kustom. Secara umum, aturan berikut diterapkan pada fungsi kustom dalam bahasa Pine:

  1. Semua fungsi didefinisikan dalam ruang lingkup global skrip. Fungsi tidak dapat dinyatakan dalam fungsi lain.
  2. Fungsi tidak diizinkan untuk memanggil diri mereka sendiri dalam kode mereka sendiri (rekursi).
  3. Pada prinsipnya, semua fungsi gambar bahasa PINE (barcolor(), fill(), hline(), plot(), plotbar(), plotcandle()) tidak dapat dipanggil dalam fungsi kustom.
  4. Fungsi dapat ditulis sebagai baris tunggal atau beberapa baris. Nilai pengembalian pernyataan terakhir adalah nilai pengembalian fungsi saat ini, yang dapat dikembalikan dalam bentuk tuple.

Kami juga telah menggunakan fungsi kustom untuk banyak kali dalam tutorial kami sebelumnya, seperti yang dirancang sebagai satu baris:

barIsUp() => close > open

Apakah BAR saat ini adalah garis positif ketika fungsi kembali.

Fungsi khusus yang dirancang untuk menjadi beberapa 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 khusus untuk mewujudkan fungsi perhitungan rata-rata sma.

Selain itu, dua contoh fungsi kustom yang bisa kita kembalikan:

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 dapat menghitung garis cepat, garis lambat dan dua rata-rata EMA.

Fungsi bawaan

Fungsi built-in dapat dengan mudah ditemukan diDokumen skrip FMZ PINE.

Klasifikasi fungsi bawaan dalam bahasa Pine:

  1. Fungsi pengolahan stringstr. series.
  2. Fungsi pemrosesan nilai warnacolor. series.
  3. Fungsi input parameterinput. series.
  4. Fungsi perhitungan indikatorta. series.
  5. Fungsi menggambarplot. series.
  6. Fungsi penanganan arrayarray. series.
  7. Fungsi yang berhubungan dengan perdaganganstrategy. series.
  8. Fungsi terkait operasi matematikamath. series.
  9. Fungsi lain (pengelolaan waktu, fungsi gambar seri non-plot,request.fungsi seri, fungsi penanganan tipe, dll.)

Fungsi Perdagangan

Peraturanstrategy.Serangkaian fungsi adalah fungsi yang sering kita gunakan dalam desain strategi, dan fungsi ini terkait erat dengan pelaksanaan operasi perdagangan ketika strategi berjalan secara khusus.


  1. strategy.entry

strategy.entryfungsi adalah fungsi yang lebih penting ketika kita menulis strategi untuk menempatkan pesanan, beberapa parameter penting untuk fungsi adalah:id, direction, qty, when, dll.

Parameter:

  • id: Ini dapat dipahami sebagai memberikan nama untuk posisi perdagangan untuk referensi.
  • direction: Jika arah pesanan panjang (beli), masukkan variabel bawaanstrategy.long, dan jika Anda ingin pergi pendek (menjual), lulus dalam variabelstrategy.short.
  • qty: Tentukan jumlah pesanan yang akan ditempatkan, jika parameter ini tidak dilewati, jumlah pesanan default akan digunakan.
  • when: Kondisi eksekusi, Anda dapat menentukan parameter ini untuk mengontrol apakah operasi order saat ini dipicu atau tidak.
  • limit: Tentukan harga batas pesanan.
  • stopHarga stop loss.

Rincian pelaksanaan khususstrategy.entryfungsi dikendalikan oleh pengaturan parameter ketikastrategyfungsi disebut, dan juga dapat dikendalikan oleh [Pine Language Trade-Class Library Template Arguments](https://www.fmz.com/bbs-topic/9293#template-arguments-of-pine-language-trade-class-library) pengaturan kontrol, Pine bahasa trade-class template library argumen kontrol lebih detail dari transaksi, Anda dapat memeriksa dokumentasi terkait untuk rincian.

Kami fokus padapyramiding, default_qty_valueparameter dalamstrategyKami menggunakan kode berikut untuk tes:

/*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)

Bagian di awal kode/* backtest... */adalah pengaturan backtest, yang digunakan untuk merekam waktu pengaturan backtest dan informasi lain pada saat itu untuk debugging, bukan kode startup.

Dalam kode:strategy(title = "open long example", pyramiding = 3, default_qty_value=0.1, overlay=true), ketika kita menentukanpyramidingparameter sebagai 3, kita mengatur jumlah maksimum perdagangan ke arah yang sama ke 3.strategy.entryOperasi order dalam contoh tidak dijalankan.default_qty_valueparameter menjadi 0,1, inistrategy.entryOperasi dengan IDlong1memiliki ukuran pesanan default 0,1.strategy.entryfungsi panggilan ketika kita menentukandirectionsebagaistrategy.long, jadi semua pesanan uji backtest adalah pesanan beli.

Perhatikan bahwa operasi orderstrategy.entry("long3", ...dalam kode dipanggil dua kali, untuk ID yang sama:long3, yang pertamastrategy.entryoperasi pesanan tidak diisi, dan panggilan kedua kestrategy.entryfungsi adalah untuk memodifikasi urutan untuk ID ini (data yang ditunjukkan dalam tes backtest juga menunjukkan bahwa kuantitas urutan untuk urutan batas ini dimodifikasi menjadi 0,3).strategy.entryfungsi untuk menempatkan pesanan sesuai dengan ID long3, maka posisi pesanan akan dikumpulkan pada ID long3.


  1. strategy.close

Peraturanstrategy.closefungsi digunakan untuk menutup posisi masuk dengan ID identifikasi yang ditentukan. Parameter utama adalah:id, when, qty, qty_percent.

Parameter:

  • id: ID entri yang perlu ditutup adalah ID yang kita tentukan ketika kita membuka posisi menggunakan fungsi order entry, sepertistrategy.entry.
  • when: Kondisi pelaksanaan.
  • qty: Jumlah posisi tertutup.
  • qty_percent: Persentase posisi tertutup.

Mari kita membiasakan diri dengan rincian penggunaan fungsi ini melalui contoh: Peraturan/*backtest ... */dalam kode adalah informasi konfigurasi untukFMZ.COMsitus web internasional backtest, Anda dapat menghapus dan mengatur pasar, varietas, rentang waktu dan informasi lain yang Anda butuhkan 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 uji menunjukkan tiga entri panjang berturut-turut dengan ID entri long1 dan kemudian menggunakan parameter yang berbeda daristrategy.closefungsi untuk mengatur hasil yang berbeda dari backtest ketika menutup posisi.strategy.closefungsi tidak memiliki parameter untuk menentukan harga pesanan untuk menutup posisi, fungsi ini terutama digunakan untuk menutup posisi segera pada harga pasar saat ini.


  1. strategy.close_all

Fungsistrategy.close_alldigunakan untuk menutup semua posisi saat ini, karena posisi skrip bahasa Pine hanya dapat memiliki arah, yaitu, jika ada sinyal dipicu dalam arah yang berlawanan dari posisi saat ini akan menutup posisi saat ini dan kemudian membukanya sesuai dengan pemicu sinyal.strategy.close_allakan menutup semua posisi dalam arah saat ini ketika dipanggil.strategy.close_allFungsi adalah:when.

Parameter:

  • when: Kondisi pelaksanaan.

Mari kita gunakan contoh untuk mengamati:

/*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 

Kode uji dimulai dengan nomor posisi 0 (yaitustrategy.position_size==0adalah benar), jadi ketika kondisi yang ditetapkan oleh ketika parameter dipenuhi, hanyastrategy.entryfungsi entri dengan ID long dijalankan. Setelah memegang posisi panjang,strategy.position_sizejika nilai nilai dari posisi long yang dipegang oleh trader adalah lebih besar dari 0, maka fungsi entry dengan ID short dapat dieksekusi, karena posisi long saat ini dipegang, sinyal pembalikan shorting ini pada saat ini akan menghasilkan penutupan posisi long dan kemudian membuka posisi short ke arah yang berlawanan.strategy.position_size < 0, yaitu ketika memegang posisi pendek, semua posisi di arah memegang saat ini akan ditutup.enableStop := true. Menghentikan pelaksanaan strategi sehingga log dapat diamati.

Hal ini dapat ditemukan bahwa fungsistrategy.close_alltidak memiliki parameter untuk menentukan harga penutupan pesanan, fungsi ini terutama digunakan untuk segera menutup posisi pada harga pasar saat ini.


  1. strategy.exit

Peraturanstrategy.exitFungsi ini digunakan untuk menutup posisi masuk.strategy.closedanstrategy.close_allfungsi menutup posisi segera pada harga pasar saat ini.strategy.exitfungsi akan menutup posisi sesuai dengan pengaturan parameter.

Parameter:

  • id: ID pengidentifikasi order dari order kondisi penutupan saat ini.
  • from_entry: Digunakan untuk menentukan ID entri posisi yang akan ditutup.
  • qty: Jumlah posisi tertutup.
  • qty_percent: Persentase posisi tertutup, kisaran: 0 ~ 100.
  • profit: Target keuntungan, dinyatakan dalam poin.
  • loss: Target stop loss, dinyatakan dalam poin.
  • limit: Target keuntungan, ditentukan oleh harga.
  • stop: Target stop loss, ditentukan oleh harga.
  • when: Kondisi pelaksanaan.

Gunakan strategi uji 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 real-time untuk backtest, strategi tes dimulai dengan 3 operasi entri (strategy.entryfungsi), danlong1sengaja diatur denganlimitparameter dengan harga order tertunda 1, sehingga tidak dapat diisi.strategy.exitKami menggunakan take profit by point dan take profit by price, penutupan sejumlah posisi yang ditetapkan, dan posisi penutupan per persen. Mengingat panjang contoh, hanya take profit yang ditunjukkan. Operasi stop loss juga sama.strategy.exitFungsi ini juga memiliki parameter trailing stop yang lebih kompleks:trail_price, trail_points, trail_offsetjuga dapat diuji dalam contoh ini untuk belajar penggunaannya.


  1. strategy.cancel

Peraturanstrategy.cancelfungsi digunakan untuk membatalkan / menghentikan semua pesanan yang belum selesai.strategy.order, strategy.entry , strategy.exitdapat menghasilkan ID entri. Parameter utama dari fungsi ini adalah:id, when.

Parameter:

  • id: ID masuk dibatalkan.
  • when: Kondisi pelaksanaan.

Fungsi ini mudah dipahami, dan 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

Lebih banyak