Tutorial pengenalan Bahasa PINE FMZ Quant

Penulis:Lydia, Dicipta: 2022-09-23 15:23:34, Dikemas kini: 2024-02-27 16:47:41

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, nzuntuk 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).

Keutamaan Pengendali

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 +-dannotdalam 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.

Variabel

Pengisytiharan Berubah

Kita telah mempelajari konsep marker sebelum ini, yang digunakan sebagai nama pembolehubah, iaitu, pembolehubah adalah penanda yang memegang nilai. jadi bagaimana kita mengisytiharkan pembolehubah? apakah peraturan untuk mengisytiharkan pembolehubah?

  • Mod Pengisytiharan: Perkara pertama yang perlu ditulis apabila mengisytiharkan pembolehubah adalah mode pengisytiharan. Terdapat tiga mod pengisytiharan untuk pembolehubah:

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

    Peraturanvardanvaripkata 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, atauswitchdan 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.

img

Kami memperkenalkan beberapa parameter utama fungsi input:

  • defval: Nilai lalai untuk pilihan parameter strategi yang ditetapkan oleh fungsi input, menyokong pembolehubah bahasa Pine, nilai numerik, dan rentetan.
  • Title: Nama parameter strategi yang dipaparkan pada antara muka strategi semasa perdagangan langsung/backtesting.
  • Tip alat: Maklumat tip alat untuk parameter strategi, apabila tetikus melayang di atas parameter strategi, maklumat teks tetapan parameter akan dipaparkan.
  • kumpulan: Nama kumpulan parameter strategi, yang boleh digunakan untuk parameter strategi.

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

Struktur Keadaan

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

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)

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

Pernyataan pertukaran

Perintah suis juga merupakan perintah bercabang, yang digunakan untuk merancang laluan yang berbeza untuk dilaksanakan mengikut keadaan tertentu.

  1. Pernyataan switch, seperti pernyataan if, juga boleh mengembalikan nilai.
  2. Tidak seperti pernyataan suis dalam bahasa lain, apabila pembinaan suis dilaksanakan, hanya blok tempatan kodnya yang dilaksanakan, jadi pernyataan putus tidak perlu (iaitu, tidak perlu menulis kata kunci seperti putus).
  3. Setiap cawangan suis boleh menulis blok kod tempatan, baris terakhir blok kod tempatan ini adalah nilai pulangan (ia boleh menjadi tuple nilai).
  4. Ungkapan dalam struktur suis menentukan kedudukan boleh menulis rentetan, pembolehubah, ungkapan atau panggilan fungsi.
  5. menukar membolehkan menentukan nilai pulangan yang bertindak sebagai nilai lalai untuk digunakan apabila tidak ada kes lain dalam struktur untuk dijalankan.

Terdapat dua bentuk suis, mari kita lihat contoh satu demi satu untuk memahami penggunaannya.

  1. Aswitchdengan 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.stringdigunakan untuk mengembalikan rentetan, daninput.intfungsi digunakan untuk mengembalikan nilai bilangan bulat. Dalam contoh, terdapat penggunaan baruoptionsparameter.optionsparameter 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.

  1. switchtanpa ungkapan

Seterusnya, 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 < openanda 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 "switchdengan ungkapan", cawangan pelaksanaan adalah deterministik dan tidak akan diubah semasa operasi strategi).

Struktur gelung

untuk penyata

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 return value dalam kod samaran di atas. Perkataan for diikuti oleh pembolehubah count yang digunakan untuk mengawal bilangan gelung, merujuk kepada nilai lain, dll.

PeraturanbreakKata kunci yang digunakan dalam gelung for: gelung berhenti apabilabreakPerintah dilaksanakan. PeraturancontinueKata kunci yang digunakan dalam gelung for: ApabilacontinuePerintah dijalankan, gelung akan mengabaikan kod selepascontinuedan 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")

untuk... dalam kenyataan

Peraturanfor ... inPerkataan 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.

  1. Mengira nilai purata

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.smajelas, lebih mudah untuk menggunakan fungsi terbina dalam untuk mengira purata bergerak. dengan membandingkan pada carta, ia dapat dilihat bahawa hasil yang dikira adalah sama.

  1. Ringkasan

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.sumuntuk 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:

  1. Untuk beberapa operasi dan pengiraan untuk array.
  2. Untuk mengkaji semula sejarah, contohnya, untuk mengetahui berapa banyak titik tinggi masa lalu yang lebih tinggi daripada titik tinggi BAR semasa.
  3. Apabila fungsi bahasa Pine terbina dalam tidak dapat menyelesaikan pengiraan untuk BARs masa lalu.

sementara statemnet

PeraturanwhilePerintah 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 loop condition adalah benar, dan menghentikan gelung apabila keadaan adalah salah.

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

Array

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

Mengisytiharkan array

Penggunaanarray<int> a, float[] buntuk 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.newdanarray.fromTerdapat 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.islastadalah benar, masih ada hanya satu elemen dicetak dengan nilai 0.

Membaca dan menulis unsur dalam array

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.

Iterate melalui elemen array

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.

Rujukan data sejarah

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)

Fungsi untuk menambah dan memadam barisan

  1. Fungsi yang berkaitan dengan operasi penjumlahan array:

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

  1. Fungsi yang berkaitan dengan operasi 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 barisan

Kita boleh membina struktur data queue dengan menggunakan array dan beberapa fungsi penambahan dan penghapusan array. Queues boleh digunakan untuk mengira purata bergerak harga tik. Seseorang mungkin bertanya, Mengapa kita harus membina struktur queue? Bukankah kita menggunakan array untuk mengira purata sebelum ini?

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 kuncivariantDengan cara ini, setiap perubahan harga akan direkodkan dalam array a.

Fungsi pengiraan dan operasi array yang biasa digunakan

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

Fungsi

Fungsi tersuai

Bahasa Pine boleh direka dengan fungsi tersuai. Secara umum, peraturan berikut digunakan untuk fungsi tersuai dalam bahasa Pine:

  1. Semua fungsi ditakrifkan dalam skop global skrip. Fungsi tidak boleh dinyatakan dalam fungsi lain.
  2. Fungsi tidak dibenarkan memanggil diri mereka dalam kod mereka sendiri (rekursi).
  3. Pada asasnya, semua fungsi lukisan bahasa PINE (barcolor(), fill(), hline(), plot(), plotbar(), plotcandle()) tidak boleh dipanggil dalam fungsi tersuai.
  4. Fungsi boleh ditulis sebagai baris tunggal atau beberapa baris. Nilai pulangan statement terakhir adalah nilai pulangan fungsi semasa, yang boleh dikembalikan dalam bentuk tuple.

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

Fungsi terbina dalam boleh dengan mudah dijumpai dalamDokumen skrip FMZ PINE.

Klasifikasi fungsi terbina dalam bahasa Pine:

  1. Fungsi pemprosesan rentetanstr. series.
  2. Fungsi pemprosesan nilai warnacolor. series.
  3. Fungsi input parameterinput. series.
  4. Fungsi pengiraan penunjukta. series.
  5. Fungsi lukisanplot. series.
  6. Fungsi pengendalian arrayarray. series.
  7. Fungsi yang berkaitan dengan perdaganganstrategy. series.
  8. Fungsi yang berkaitan dengan operasi matematikmath. series.
  9. Fungsi lain (pengendalian masa, fungsi lukisan siri bukan grafik,request.fungsi siri, fungsi pengendalian jenis, dan lain-lain)

Fungsi Perdagangan

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.


  1. strategy.entry

strategy.entryfungsi 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.entryfungsi dikawal oleh tetapan parameter apabilastrategyfungsi dipanggil, dan ia juga boleh dikawal oleh [Pine Language Trade-Class Library Template Arguments](https://www.fmz.com/bbs-topic/9293#template-arguments-of-pine-language-trade-class-library) menetapkan kawalan, argumen templat perpustakaan kelas perdagangan bahasa Pine mengawal lebih banyak butiran mengenai transaksi, anda boleh menyemak dokumentasi yang disambungkan untuk butiran.

Kami memberi tumpuan kepadapyramiding, default_qty_valueparameter dalamstrategyKami 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 menentukanpyramidingparameter sebagai 3, kita menetapkan bilangan maksimum perdagangan dalam arah yang sama kepada 3.strategy.entryOperasi perintah dalam contoh tidak dilaksanakan.default_qty_valueparameter untuk menjadi 0.1, inistrategy.entryoperasi dengan IDlong1mempunyai saiz pesanan lalai 0.1.strategy.entrypanggilan fungsi apabila kita menentukandirectionsebagaistrategy.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.entryoperasi pesanan tidak diisi, dan panggilan kedua kepadastrategy.entrySatu lagi kes, contohnya, jika urutan pertama dengan ID long3 diisi, teruskan menggunakanstrategy.entryfungsi untuk meletakkan pesanan mengikut ID long3, maka kedudukan pesanan akan dikumpulkan pada ID long3.


  1. strategy.close

Peraturanstrategy.closeFungsi 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 long1 dan kemudian menggunakan parameter yang berbeza daristrategy.closefungsi untuk menetapkan hasil yang berbeza dari backtest apabila menutup kedudukan.strategy.closefungsi ini tidak mempunyai parameter untuk menentukan harga pesanan untuk menutup kedudukan, fungsi ini digunakan terutamanya untuk menutup kedudukan dengan segera pada harga pasaran semasa.


  1. strategy.close_all

Fungsistrategy.close_alldigunakan 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_allakan menutup semua kedudukan dalam arah semasa apabila ia dipanggil.strategy.close_allFungsi 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==0adalah benar), jadi apabila syarat yang ditetapkan oleh apabila parameter dipenuhi, hanyastrategy.entryfungsi kemasukan dengan ID long dijalankan. Selepas memegang kedudukan panjang,strategy.position_sizeadalah lebih besar daripada 0, maka fungsi kemasukan dengan ID short boleh dilaksanakan, kerana kedudukan panjang semasa dipegang, isyarat pembalikan pendek ini pada masa ini akan mengakibatkan penutupan kedudukan panjang dan kemudian membuka kedudukan pendek ke arah yang bertentangan.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_allmempunyai tiada parameter untuk menentukan harga penutupan pesanan, fungsi ini digunakan terutamanya untuk segera menutup kedudukan pada harga pasaran semasa.


  1. strategy.exit

Peraturanstrategy.exitfungsi digunakan untuk menutup kedudukan kemasukan.strategy.closedanstrategy.close_allfungsi menutup kedudukan dengan serta-merta pada harga pasaran semasa.strategy.exitfungsi 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.entryfungsi), danlong1ditetapkan dengan sengaja denganlimitparameter dengan harga pesanan menunggu 1, supaya ia tidak boleh diisi. kemudian menguji fungsi keluar bersyaratstrategy.exitKami menggunakan take profit by point dan take profit by price, penutupan bilangan kedudukan yang tetap, dan penutupan kedudukan peratusan. Memandangkan panjang contoh, hanya take profit ditunjukkan. Operasi stop-loss juga sama.strategy.exitfungsi juga mempunyai parameter trailing berhenti yang lebih kompleks:trail_price, trail_points, trail_offsetjuga boleh diuji dalam contoh ini untuk belajar penggunaan mereka.


  1. strategy.cancel

Peraturanstrategy.cancelfungsi digunakan untuk membatalkan / menghentikan semua pesanan yang belum selesai.strategy.order, strategy.entry , strategy.exitboleh 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

Lebih lanjut