Sumber dimuat naik... memuat...

Pencipta Kuantitatif Tutorial Pengenalan Bahasa PINE

Penulis:Pencipta Kuantiti - Impian Kecil, Dicipta: 2022-05-30 16:23:43, Dikemas kini: 2022-09-28 17:10:21

Contohnya:

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)

Perhatian: ungkapan yang digunakan untuk membuat keputusan, mengembalikan nilai Boolean. Perhatikan penyusutan. Paling banyak hanya boleh mempunyai satu cabangelse. Semua ungkapan cabang tidak benar, dan tiada cabangelse, maka ia akan mengembalikan na.

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

Oleh kerana apabila garis K BAR adalah garis menhir, iaitu apabila close < open, ungkapan selepas pernyataan if adalah false, maka blok kod tempatan if tidak dilaksanakan. Pada masa ini juga tidak ada cabangelse, pernyataan if akan mengembalikan na. x diberi nilai sebagai na.

Perkataan switch

Perkataan switch juga merupakan perkataan dengan struktur cabang yang digunakan untuk merancang untuk melaksanakan laluan yang berbeza mengikut keadaan tertentu. Perkataan switch umumnya mempunyai beberapa titik pengetahuan utama seperti berikut:

1, kata ganti boleh kembali nilai seperti kata if. 2. Tidak seperti kata laluan dalam bahasa lain, apabila melaksanakan struktur suis, hanya satu blok tempatan dalam kodnya yang dilaksanakan, jadi pengisytiharan break tidak diperlukan (iaitu tidak perlu menulis kata kunci seperti break). 3. Setiap cawangan Switch boleh menulis satu blok kod tempatan, baris terakhir blok kod tempatan ini adalah nilai yang dikembalikan (ia boleh menjadi unsur nilai). Jika tiada blok kod tempatan yang dihubungkan dijalankan, ia akan dikembalikan na. 4. Pengesahan kedudukan ekspresi dalam struktur suis, yang boleh menulis strings, variabel, ungkapan atau panggilan fungsi. 5. Switch membolehkan menentukan nilai pulangan yang digunakan sebagai nilai lalai apabila tiada keadaan lain dalam struktur dijalankan.

Kita akan melihat contoh-contohnya untuk mengetahui kegunaannya.

1 dengan ungkapanswitchContoh yang jelas:

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

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

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

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

Sebelum ini, kita belajar fungsi input, dan di sini kita terus belajar dua fungsi yang serupa dengan input:input.stringinput.intFungsi tersebut.input.stringUntuk mendapatkan semula strings, anda perlu mengklik pada gambar di bawah.input.intFungsi ini digunakan untuk mengembalikan bilangan bulat.optionsPenggunaan parameteroptionsParameter boleh dihantar ke dalam satu susunan yang terdiri daripada nilai pilihan; contohnya dalam contohoptions=["EMA", "SMA", "RMA", "WMA"]danoptions=[5, 10, 20](Perhatikan bahawa satu adalah jenis tali dan satu adalah jenis nombor). Dengan cara ini, kawalan pada antara muka dasar tidak memerlukan input nombor tertentu, tetapi kawalan menjadi kotak turun, memilih pilihan yang disediakan dalam parameter pilihan.

Nilai pembolehubah func adalah satu baris, pembolehubah func sebagai satu ungkapan untuk suis (boleh menjadi pembolehubah, panggilan fungsi, ungkapan), untuk menentukan cabang mana dalam suis yang dijalankan. Jika pembolehubah func tidak dapat mencocokkan ungkapan pada mana-mana cabang dalam suis, blok kod cawangan lalai akan dijalankan, yang akan dijalankan.runtime.error("error")Fungsi menyebabkan dasar membuang hentian yang luar biasa.

Dalam kod ujian kami di atas, selepas baris terakhir runtime.error blok kod cawangan lalai Switch, kami tidak memasukkan kod seperti [na, na] untuk mengembalikan nilai yang serasi, dan dalam pandangan perdagangan perlu mempertimbangkan masalah ini, jika jenis tidak serasi akan memberikan kesalahan. Tetapi pada FMZ, kod serasi ini boleh diabaikan kerana tidak ada keperluan jenis yang ketat.

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 akan dilaporkan di FMZ, tetapi akan dilaporkan di trading view; kerana if cabang yang dikembalikan tidak sepadan dengan jenisnya.

2. Tiada ungkapan.switch

Mari kita lihat.switchCara lain yang digunakan ialah menulis 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)

Contoh kod ujian dapat dilihat bahawa Switch akan mencocokkan blok kod tempatan yang benar dengan syarat pelaksanaan cawangan. Secara umum, syarat cawangan selepas pernyataan Switch mesti saling bertentangan. Artinya, up dan down dalam contoh ini tidak boleh benar pada masa yang sama. Oleh kerana Switch hanya dapat melaksanakan satu blok kod tempatan cawangan, ada minat untuk memasukkan ayat ini dalam kod:up = close > open // up = close < openSebagai ganti isi dalam komen, periksa semula hasil observasi. Anda akan mendapati bahawa cawangan suis hanya dapat melaksanakan cawangan pertama. Selain itu, anda juga perlu berhati-hati untuk tidak menulis panggilan fungsi di dalam cawangan suis, fungsi tidak dapat dipanggil di setiap BAR yang boleh menyebabkan beberapa masalah pengiraan data (kecuali jika "dengan ungkapanswitchDalam contoh ini, cawangan pelaksanaan ditentukan dan tidak akan diubah semasa strategi berjalan.)

Struktur kitaran

Perkataan for

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

Perkataan for sangat mudah digunakan, apabila kitaran for akhirnya boleh mengembalikan satu nilai ((atau mengembalikan beberapa nilai, dalam bentuk seperti [a, b, c]) ; seperti dalam kod palsu di atas, pembagian kepada pembolehubah yang diberi kedudukan "nilai pulangan". Perkataan for diikuti oleh pembolehubah "pengiraan" untuk mengawal bilangan kitaran, merujuk kepada nilai lain, dan lain-lain. Pembolehubah "pengiraan" diberi nilai "pengiraan awal" sebelum kitaran bermula, dan kemudian disalurkan mengikut tetapan "pertumbuhan", dan kitaran berhenti apabila jumlah "pengiraan" lebih besar daripada "pengiraan akhir".

untuk digunakan dalam kitaranbreakKata Kunci: Apabila dilaksanakanbreakSelepas kalimat, kitaran berhenti. untuk digunakan dalam kitarancontinueKata Kunci: Apabila dilaksanakancontinueSelepas ayat, kitaran akan diabaikan.continueKod selepas itu, langsung menjalankan pusingan seterusnya. Perkataan for mengembalikan nilai yang dikembalikan semasa pusingan terakhir dijalankan. Jika tidak ada kod yang dijalankan, nilai kosong dikembalikan.

Di bawah ini kita akan menunjukkan dengan contoh mudah:

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

Perkataan for... in

for ... inPerkataan ini mempunyai dua bentuk, di mana kod palsu berikut menunjukkannya.

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

Perbezaan utama antara kedua-dua bentuk adalah dalam apa yang diikuti selepas kata kunci for. Salah satu adalah menggunakan satu pembolehubah sebagai pembolehubah yang merujuk kepada elemen matriks. Satu lagi adalah menggunakan struktur pembolehubah yang mengandungi pembolehubah indeks, elemen matriks. Yang lain menggunakan peraturan nilai pulangan, menggunakan peraturan seperti break, teruskan dan berpusing for.

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

runtime.error("stop")

Jika anda memerlukan indeks, gunakan.for [i, ele] in testArrayPerkataan ini ditulis oleh:

for aplikasi berputar

Apabila fungsi terbina dalam yang disediakan oleh bahasa Pine dapat melakukan beberapa pengiraan logik berputar, struktur berputar boleh ditulis secara langsung, atau pemprosesan fungsi terbina dalam boleh digunakan. Kami memberikan dua contoh.

1, kiraan purata

Menggunakan reka bentuk struktur berputar:

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)

Dalam contoh ini, pengiraan putaran for digunakan, dan nilai rata dikira.

Menggunakan fungsi terbina dalam untuk mengira garis rata secara langsung:

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

Menggunakan fungsi terbina dalam secara langsungta.sma, pengiraan penunjuk rata-rata, jelas lebih mudah untuk pengiraan rata-rata menggunakan fungsi terbina dalam. Pada carta perbandingan, anda dapat melihat hasil pengiraan yang sama sepenuhnya.

2.

Atau gunakan contoh di atas untuk menerangkannya.

Menggunakan reka bentuk struktur berputar:

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 semua elemen array yang boleh diuruskan dengan gelung, fungsi terbina dalam juga boleh digunakanarray.sumPergilah ke perhitungan. Menghitung penjumlahan 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)

Anda boleh melihat data yang dikira, menggunakan gambar plot untuk menunjukkan keserasian penuh pada carta.

Jika semua ini boleh dilakukan dengan fungsi terbina dalam, mengapa kita merancang gelung? 1, beberapa operasi untuk aritmatika, pengiraan. 2, mengulas sejarah, sebagai contoh, mencari berapa banyak puncak masa lalu yang lebih tinggi daripada puncak BAR semasa. Oleh kerana puncak BAR semasa hanya diketahui pada BAR yang dijalankan oleh skrip, ia memerlukan gelung untuk kembali pada masa yang sesuai dan menganalisis BAR masa lalu. 3. Fungsi terbina dalam yang menggunakan bahasa Pine tidak dapat menyelesaikan pengiraan BAR masa lalu.

Perkataan while

whilePerkataan membolehkan kod bagi bahagian berputar dijalankan sehingga syarat penghakiman dalam struktur while adalah palsu.

返回值 = while 判断条件
    语句                    // 注释:语句里可以有break,continue
    语句                    // 注释:最后一条语句为返回值

Peraturan lain untuk while adalah sama seperti untuk gelung, baris terakhir blok kod tempatan gelung adalah nilai pulangan, yang boleh mengembalikan pelbagai nilai. Apabila "kondisi gelung" adalah untuk menjalankan gelung pada masa yang sebenarnya, keadaan adalah untuk menghentikan gelung.

Saya masih menggunakan contoh garis lurus untuk menunjukkan:

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)

Seperti yang dapat dilihat, penggunaan loop sementara juga sangat mudah, dan juga boleh merancang beberapa logika pengiraan yang tidak dapat digantikan dengan fungsi terbina dalam, seperti pengiraan pangkat:

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

Kumpulan

Array dalam bahasa Pine mempunyai definisi yang sama dengan dalam bahasa pengaturcaraan lain, iaitu array dalam bahasa Pine adalah satu dimensi; biasanya digunakan untuk menyimpan satu siri data berturut-turut; array yang mana data tunggal yang disimpan dipanggil elemen array, jenis elemen ini boleh menjadi: bulat, titik lebat, baris, nilai warna, nilai bul; dan bahasa Pine pada FMZ tidak begitu ketat mengenai jenis, bahkan boleh menyimpan baris dan nilai pada masa yang sama dalam satu array; dan kerana lapisan bawah array juga merupakan struktur siri, jika menggunakan operator sejarah merujuk kepada keadaan ar array pada bar sebelumnya, maka tidak menggunakan operator sejarah untuk merujuk kepada elemen dalam array.[]Ia perlu digunakan.array.get()danarray.set()Fungsi. Urutan indeks elemen dalam matriks ialah indeks elemen pertama matriks adalah 0, indeks elemen seterusnya meningkat 1.

Kami akan menerangkan dengan kod yang mudah:

var a = array.from(0)
if bar_index == 0 
    runtime.log("当前BAR上的a值:", a, ", 上1根BAR上的a,即a[1]值:", a[1])
else if bar_index == 1 
    array.push(a, bar_index)
    runtime.log("当前BAR上的a值:", a, ", 上1根BAR上的a,即a[1]值:", a[1])
else if bar_index == 2
    array.push(a, bar_index)
    runtime.log("当前BAR上的a值:", a, ", 上1根BAR上的a,即a[1]值:", a[1], ", 向前数2根BAR上的a,即a[2]值:", a[2])
else if bar_index == 3 
    array.push(a, bar_index)
    runtime.log("当前BAR上的a值:", a, ", 上1根BAR上的a,即a[1]值:", a[1], ", 向前数2根BAR上的a,即a[2]值:", a[2], ", 向前数3根BAR上的a,即a[3]值:", a[3])
else if bar_index == 4 
    // 使用array.get 按索引获取元素,使用array.set按索引修改元素
    runtime.log("数组修改前:", array.get(a, 0), array.get(a, 1), array.get(a, 2), array.get(a, 3))
    array.set(a, 1, 999)
    runtime.log("数组修改后:", array.get(a, 0), array.get(a, 1), array.get(a, 2), array.get(a, 3))

Array pengisytiharan

Penggunaanarray<int> afloat[] bArray yang diisytiharkan atau hanya menyatakan satu pembolehubah boleh diberi nilai sebagai 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")

Inisialisasi pemboleh ubah untuk matriks digunakan secara umumarray.newdanarray.from函数。Pine语言中还有很多和类型相关的与array.new类似的函数:array.new_int()array.new_bool()array.new_color()array.new_string()Seperti itu.

Kata kunci var juga boleh berfungsi dengan pola pengisytiharan array, yang menggunakan pernyataan kata kunci var untuk mengisytiharkan array hanya pada BAR pertama. Kita melihat dengan satu 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")

Seperti yang dapat dilihat, perubahan dalam array a sentiasa ditetapkan dan tidak ditempatkan semula. Array b diinstalikan pada setiap BAR.barstate.islastUntuk mencetak secara real-time, masih ada satu elemen, nilai 0 ≠ 0.

Membaca dan menulis elemen dalam array

Menggunakan array.get untuk mendapatkan elemen yang menetapkan kedudukan indeks dalam suatu array, menggunakan array.set untuk mengubah elemen yang menetapkan kedudukan indeks dalam suatu array.

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

Contoh mudah untuk menunjukkannya ialah:

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, menyatakan dan mengisytiharkan satu matriks untuk menyimpan warna, dan kemudian memberikan ketelusan yang berbeza kepada nilai warna (menggunakan fungsi color.new). Mengira kedudukan warna dengan mengira jarak maksimum nilai high dalam 100 kitaran semakan semasa BAR; semakin dekat nilai maksimum tinggi dalam 100 kitaran semakan terkini, semakin tinggi kedudukan, semakin mendalam nilai warna yang sesuai (kekurangan ketelusan); banyak strategi yang sama digunakan dengan cara ini untuk menyatakan tahap harga dalam N kitaran semakan semasa.

Melalui unsur-unsur array

Bagaimana untuk melintasi suatu artifak, kita boleh melakukannya dengan kata-kata for/for in/while yang kita pelajari 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")

Kesemua tiga kaedah ini mempunyai hasil yang sama.

Aras boleh diisytiharkan dalam jangkaan global skrip, atau diisytiharkan dalam jangkaan tempatan fungsi atau cabang if

Sumber data sejarah

Untuk penggunaan elemen dalam array, cara berikut adalah sama, kita dapat melihat dengan contoh berikut bahawa dua kumpulan baris digambar pada grafik, dua baris setiap kumpulan, dan dua baris setiap kumpulan 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)

Menambah aritmatika, memadamkan fungsi operasi

1, fungsi yang berkaitan dengan operasi penambahan matriks:

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

2, fungsi berkaitan operasi penghapusan artifak:

array.remove()array.shift()array.pop()array.clear()

Kami menggunakan contoh berikut untuk menguji fungsi operasi penambahan, penyingkiran, dan penghapusan.

a = array.from("A", "B", "C")
ret = array.unshift(a, "X")
runtime.log("数组a:", a, ", ret:", ret)

ret := array.insert(a, 1, "Y")
runtime.log("数组a:", a, ", ret:", ret)

ret := array.push(a, "D")
runtime.log("数组a:", a, ", ret:", ret)

ret := array.remove(a, 2)
runtime.log("数组a:", a, ", ret:", ret)

ret := array.shift(a)
runtime.log("数组a:", a, ", ret:", ret)

ret := array.pop(a)
runtime.log("数组a:", a, ", ret:", ret)

ret := array.clear(a)
runtime.log("数组a:", a, ", ret:", ret)

runtime.error("stop")

Aplikasi penambahan dan penghapusan: Array sebagai barisan

Dengan menggunakan array, dan beberapa fungsi penambahan dan penghapusan array, kita boleh membina struktur data "baris". Baris boleh digunakan untuk mengira purata bergerak harga tik.

Kuil adalah satu struktur yang sering digunakan dalam bidang pengaturcaraan. Kuil mempunyai ciri sebagai berikut:

Elemen yang masuk ke barisan pertama, keluar barisan pertama.

Ini memastikan bahawa data yang ada dalam barisan adalah data terkini, dan panjang barisan tidak akan membesar tanpa batas (kode yang membesar tanpa batas hanya boleh ditulis pada waktu tengah hari, kerana pagi atau petang akan menjadi masalah).

Contoh di bawah ini menggunakan struktur larik untuk merakam harga setiap tik, mengira harga purata bergerak pada tahap tik, dan kemudian membandingkan dengan pemerhatian 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, apabila kita menyatakan array a, kita telah menetapkan mode pengisytiharan, menggunakan kata kunci.varip.. Sehingga setiap perubahan harga akan dicatat dalam matriks a..

Pengiraan aritmatika yang biasa digunakan, fungsi operasi

Mengira fungsi yang berkaitan:

array.avg()Perbandingan semua unsur dalam suatu himpunan.array.min()Ini adalah nombor yang paling kecil dalam artifak.array.max()Ini adalah nombor yang paling besar.array.stdev()Ini adalah satu kaedah yang sangat mudah untuk menentukan kadar kelembapan.array.sum()Jumlah semua elemen dalam artifak.

Fungsi yang berkaitan dengan operasi:array.concat()Menggabungkan atau menghubungkan dua array.array.copy()Menggandakan Array.array.joinMenghubungkan semua elemen dalam array ke dalam satu tali.array.sort()Perintah mengikut susunan naik atau turun.array.reverse()Rangkaian pembalikan.array.slice()Mengurangkan bilangan.array.includes()Penghakiman unsur.array.indexof()Kembali ke indeks di mana nilai parameter yang dihantar pertama kali muncul. Jika nilai ini tidak dapat dijumpai, kembali -1.array.lastindexof()Cari nilai yang terakhir muncul.

Contoh ujian untuk fungsi yang berkaitan dengan pengiraan aritmatika:

a = array.from(3, 2, 1, 4, 5, 6, 7, 8, 9)

runtime.log("数组a的算数平均:", array.avg(a))
runtime.log("数组a中的最小元素:", array.min(a))
runtime.log("数组a中的最大元素:", array.max(a))
runtime.log("数组a中的标准差:", array.stdev(a))
runtime.log("数组a的所有元素总和:", array.sum(a))
runtime.error("stop")

Ini adalah fungsi aritmatika yang paling biasa digunakan.

Contoh fungsi yang berkaitan:

a = array.from(1, 2, 3, 4, 5, 6)
b = array.from(11, 2, 13, 4, 15, 6)

runtime.log("数组a:", a, ", 数组b:", b)
runtime.log("数组a,数组b连接在一起:", array.concat(a, b))
c = array.copy(b)

runtime.log("复制一个数组b,赋值给变量c,变量c:", c)

runtime.log("使用array.join处理数组c,给每个元素中间增加符号+,连接所有元素结果为字符串:", array.join(c, "+"))
runtime.log("排序数组b,按从小到大顺序,使用参数order.ascending:", array.sort(b, order.ascending))     // array.sort函数修改原数组
runtime.log("排序数组b,按从大到小顺序,使用参数order.descending:", array.sort(b, order.descending))   // array.sort函数修改原数组

runtime.log("数组a:", a, ", 数组b:", b)
array.reverse(a)   // 此函数修改原数组
runtime.log("反转数组a中的所有元素顺序,反转之后数组a为:", a)    

runtime.log("截取数组a,索引0 ~ 索引3,遵循左闭右开区间规则:", array.slice(a, 0, 3))
runtime.log("在数组b中搜索元素11:", array.includes(b, 11))
runtime.log("在数组a中搜索元素100:", array.includes(a, 100))
runtime.log("将数组a和数组b连接,搜索其中第一次出现元素2的索引位置:", array.indexof(array.concat(a, b), 2), " , 参考观察 array.concat(a, b):", array.concat(a, b))
runtime.log("将数组a和数组b连接,搜索其中最后一次出现元素6的索引位置:", array.lastindexof(array.concat(a, b), 6), " , 参考观察 array.concat(a, b):", array.concat(a, b))

runtime.error("stop")

Fungsi

Fungsi tersuai

Bahasa Pine boleh merancang fungsi kustom, dan secara amnya, fungsi kustom bahasa Pine mempunyai peraturan berikut:

1, semua fungsi ditakrifkan dalam ruang global skrip. Tidak boleh mengisytiharkan satu fungsi dalam fungsi lain. 2. Tidak membenarkan fungsi memanggil dirinya sendiri dalam kodnya sendiri. 3. Pada asasnya semua bahasa PINE mempunyai fungsi gambar terbina dalambarcolor()、 fill()、 hline()、plot()、 plotbar()、 plotcandle()) tidak boleh dipanggil dalam fungsi tersuai. 4. Fungsi boleh ditulis sebagai baris tunggal, baris berbilang. Nilai pulangan pada ayat terakhir adalah nilai pulangan fungsi semasa, nilai pulangan boleh dikembalikan dalam bentuk unsur.

Dalam tutorial sebelumnya, kita juga telah menggunakan fungsi tersuai beberapa kali, seperti merancang fungsi tersuai dalam satu baris:

barIsUp() => close > open

Fungsi ini mengembalikan sama ada BAR semasa adalah sinar matahari.

Ia direka sebagai fungsi kustom 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)

Fungsi yang dihitung pada rata-rata SMA yang kita sendiri melaksanakan dengan fungsi kustom.

Juga, contoh fungsi kustom dengan dua pembolehubah boleh dikembalikan:

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 cepat, garis perlahan, dua petunjuk EMA yang rata-rata.

Fungsi terbina dalam

Fungsi terbina dalam boleh digunakan dengan mudah diFMZ PINE Script dokumentasiPermintaan di tengah-tengah.

Fungsi terbina dalam bahasa Pine:

1, fungsi pengendalian barisstr.Kumpulan. 2, fungsi pemprosesan nilai warnacolor.Kumpulan. 3, fungsi input parameterinput.Kumpulan. 4, fungsi pengiraan penunjukta.Kumpulan. 5, fungsi gambarplot.Kumpulan. 6. Fungsi pemprosesan aritmatikaarray.Kumpulan. 7. Fungsi berkaitan transaksistrategy.Kumpulan. 8. Fungsi yang berkaitan dengan operasi matematikmath.Kumpulan. 9, Fungsi lain ((pengendalian masa, fungsi gambar siri bukan plot,request.Fungsi siri, fungsi pemprosesan jenis, dan lain-lain) ^

Fungsi urus niaga

strategy.Fungsi siri adalah fungsi yang sering kita gunakan dalam reka bentuk strategi, yang berkaitan dengan menjalankan operasi dagangan ketika strategi dijalankan secara khusus.


1、strategy.entry

strategy.entryFungsi adalah fungsi yang lebih penting ketika kita menulis strategi. Fungsi ini mempunyai beberapa parameter yang lebih penting:id, direction, qty, whenSeperti itu.

Parameter:

  • id: boleh difahami sebagai merujuk kepada nama untuk kedudukan dagangan tertentu.
  • direction: jika arah pesanan adalah untuk melakukan lebih (membeli) parameter ini akan dihantarstrategy.longVariabel terbina dalam ini akan dihantar jika anda mahu kosongkan (menjual).strategy.shortIni adalah pembolehubah.
  • qty: menentukan jumlah pesanan, jika parameter ini tidak dihantar, jumlah pesanan secara lalai akan digunakan.
  • when: syarat pelaksanaan, anda boleh menetapkan parameter ini untuk mengawal sama ada operasi bawah perintah semasa akan dicetuskan.
  • limit: Tentukan harga terhad pesanan.
  • stop: harga henti rugi.

strategy.entryPerincian pelaksanaan fungsi tertentustrategyPengendalian parameter ketika fungsi dipanggil juga boleh dilakukan melalui"Parameter Templat Perpustakaan Pertukaran Bahasa Pine"Mengatur kawalan, Parameter Template Perpustakaan Perdagangan Bahasa Pine Untuk maklumat lanjut mengenai kawalan urus niaga, lihat dokumentasi di sini.

Di sini, kita akan membincangkan perkara-perkara penting.strategyDalam fungsi ini,pyramidingdefault_qty_valueParameter. Uji menggunakan kod berikut:

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

Permulaan kod/*backtest ... */Bahagian pakej ditetapkan untuk mengulangi, untuk merakam maklumat seperti masa pengaturan pengulingan semula pada masa itu, untuk memudahkan penyusunan semula, bukan kod dasar.

Di dalam kod:strategy(title = "open long example", pyramiding = 3, default_qty_value=0.1, overlay=true)Apabila kita menetapkanpyramidingApabila parameter adalah 3, kita menetapkan untuk berdagang dalam arah yang sama sebanyak tiga kali. Jadi empat kali dalam contoh ini.strategy.entrySatu operasi di bawah tidak dilaksanakan. Kerana kita juga menetapkandefault_qty_valueParameter adalah 0.1, jadi ID akan menjadi 1 ton untuk kali ini.strategy.entryJumlah pesanan untuk operasi sub-order ditetapkan sebagai lalai 0.1.strategy.entryFungsi yang kita tentukan untuk dipanggildirectionsama ratastrategy.longOleh itu, anda perlu membayar untuk mendaftar untuk ujian semula.

Perhatikan dalam kodstrategy.entry("long3", ...Operasi berikut dipanggil dua kali, untuk ID yang sama: long3.strategy.entryOperasi di bawah tidak berjaya, panggilan keduastrategy.entryFungsi untuk mengubah ID ini untuk pesanan ((Data yang ditunjukkan semasa ujian semula juga dapat melihat bahawa jumlah pesanan di bawah pesanan terhad ini telah diubah menjadi 0.3)).strategy.entryJika anda meletakkan pesanan, maka semua kedudukan pesanan akan terkumpul pada ID long 3.


2、strategy.close

strategy.closeFungsi ini digunakan untuk menentukan ID pengenalan pegangan masuk. Parameter utama ialah:idwhenqtyqty_percent

Parameter:

  • id: ID masuk yang diperlukan untuk meletakkan, iaitu yang kita gunakanstrategy.entryID yang ditetapkan semasa membuka dagangan pada fungsi masuk.
  • when: Syarat pelaksanaan.
  • qty: Jumlah pelaburan.
  • qty_percent: Peratusan pelaburan.

Untuk mengetahui perincian penggunaan fungsi ini, lihat contoh berikut: Dalam kod/*backtest ... */是FMZ.COM国际站回测时的配置信息,可以删掉,设置自己需要测试的市场、品种、时间范围等信息。

/*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")                   // 多个入场订单,不指定qty参数,全部平仓
    // strategy.close()                          // 不指定id参数,会平掉当前的持仓
    // strategy.close("long2")                   // 如果指定一个不存在的id则什么都不操作
    // strategy.close("long1", qty=0.15)         // 指定qty参数平仓
    // strategy.close("long1", qty_percent=50)   // qty_percent设置50即为平掉long1标识仓位的50%持仓
    // strategy.close("long1", qty_percent=80, when=close<open)  // 指定when参数,修改为close>open就不触发了
    enableStop := true

Kaedah ujian menunjukkan mulakan tiga kali berturut-turut melakukan banyak log masuk, ID log masuk masing-masing 1long, dan kemudian gunakanstrategy.closeHasil yang berbeza yang dipetik semula apabila parameter yang berbeza untuk fungsi ditetapkan pada kedudukan rata.strategy.closeFungsi ini tidak mempunyai parameter untuk menentukan harga pesanan yang akan ditarik ke pasaran, dan berfungsi untuk menanamkan harga yang akan ditarik ke pasaran sekarang.


3、strategy.close_all

strategy.close_allFungsi ini digunakan untuk meratakan semua pegangan semasa, kerana skrip pegangan bahasa Pine hanya boleh berlaku dalam satu arah, iaitu jika terdapat isyarat yang bertentangan dengan arah pegangan semasa, ia akan meratakan pegangan semasa dan mencetuskan perdagangan berdasarkan isyarat tersebut.strategy.close_allApabila dipanggil, semua pegangan di arah semasa akan dipadamkan.strategy.close_allParameter utama fungsi ialah:when

Parameter:

  • when: Syarat pelaksanaan.

Kami menggunakan satu contoh untuk melihat:

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

Pada permulaan kod ujian, jumlah simpanan adalah 0 (iaitustrategy.position_size==0Jadi, apabila syarat seting parameter when dipenuhi, ID hanya akan dijalankan sebagai yang terpendam.strategy.entryFungsi masuk. Selepas memegang banyak kedudukanstrategy.position_sizeApabila ID adalah lebih besar daripada 0, maka fungsi masuk untuk penyamaran pendek mungkin akan dilaksanakan. Oleh kerana banyak kedudukan yang dipegang pada masa ini, isyarat pembalikan kosong yang muncul pada masa ini akan menyebabkan pembukaan balik setelah memegang banyak kedudukan. Kemudian kita menulis dalam syarat if apabilastrategy.position_size < 0Apabila memegang, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang kosong, memegang, memegangenableStop := true◦ Menghentikan pelaksanaan untuk memudahkan pengguna melihat log tersebut.

Di sini terdapatstrategy.close_allFungsi ini tidak mempunyai parameter untuk menentukan harga pesanan yang akan ditarik ke pasaran, dan berfungsi untuk menanamkan harga yang akan ditarik ke pasaran sekarang.


4、strategy.exit

strategy.exitFungsi ini digunakan untuk operasi kedudukan yang masuk dalam saham, berbeza dengan fungsi ini.strategy.closedanstrategy.close_allFungsi ini adalah penempatan segera pada harga pasaran semasa.strategy.exitFungsi akan membuat perancangan permaidani mengikut tetapan parameter.

Parameter:

  • id: ID pesanan untuk senarai syarat pelaburan semasa ini.
  • from_entry: Digunakan untuk menentukan ID masuk untuk melakukan operasi perpecahan.
  • qty: Jumlah pelaburan.
  • qty_percent: Peratusan pegangan rata, julat: 0 ~ 100.
  • profit: sasaran keuntungan, dinyatakan dengan mata.
  • loss: sasaran stop loss, dilambangkan dengan nombor titik.
  • limit: sasaran keuntungan, harga ditetapkan.
  • stop: sasaran stop loss, dengan harga tertentu.
  • when: Syarat pelaksanaan.

Menggunakan 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")          // 如果仅仅指定一个id参数,则该退场订单无效,参数profit, limit, loss, stop等出场条件也至少需要设置一个,否则也无效
    strategy.exit("exit1", "long1", profit=50)                    // 由于long1入场订单没有成交,因此ID为exit1的出场订单也处于暂待状态,直到对应的入场订单成交才会放置exit1
    strategy.exit("exit2", "long2", qty=0.1, profit=100)          // 指定参数qty,平掉ID为long2的持仓中0.1个持仓
    strategy.exit("exit3", "long3", qty_percent=50, limit=strategy.opentrades.entry_price(findOrderIdx("long3")) + 1000)   // 指定参数qty_percent,平掉ID为long3的持仓中50%的持仓
    isExit := true 

if bar_index == 0 
    runtime.log("每点价格为:", syminfo.mintick)    // 每点价格和Pine语言模板参数上「定价货币精度」参数设置有关

Menggunakan ujian semula model harga masa nyata, strategi ujian ini bermula dengan menjalankan 3 operasi masuk.strategy.entryFungsi), yang ditetapkan secara sengaja untuklimitParameter, harga pesanan yang dilampirkan adalah 1 yang menyebabkan ia tidak dapat ditangani. Kemudian uji syarat keluar fungsistrategy.exit◦ Menggunakan stop stop stop berdasarkan bilangan titik, stop stop berdasarkan harga, menggunakan jumlah kedudukan yang tetap, menggunakan peratusan kedudukan. ◦ Mengingat contoh artikel ini hanya menunjukkan stop stop. Operasi stop loss juga adalah simetri.strategy.exitFungsi ini juga mempunyai parameter penghentian kehilangan yang lebih rumit:trail_pricetrail_pointstrail_offsetAnda juga boleh menguji cara menggunakannya dalam contoh ini.


5、strategy.cancel

strategy.cancelFungsi digunakan untuk membatalkan / menghentikan semua arahan yang telah diletakkan.strategy.order, strategy.entry , strategy.exitBoleh menghasilkan ID masuk. Parameter utama fungsi ini ialah:idwhen

Parameter:

  • id: ID masuk yang ingin dibatalkan.
  • when: Syarat pelaksanaan.

Fungsi ini sangat mudah difahami kerana digunakan untuk membatalkan perintah masuk tanpa transaksi.

/*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.3, limit=3)

if not barstate.ishistory and close < open 
    strategy.cancel("long1")
    strategy.cancel("long2")
    strategy.cancel("long3")
    isStop := true 

6、strategy.cancel_all

strategy.cancel_allFungsi danstrategy.cancelFungsi serupa seperti: === Menghapuskan/menghentikan semua perintah yang telah diletakkan=== boleh ditentukanwhenParameter.

Parameter:

  • when: Syarat pelaksanaan.
/*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.3, limit=3)

if not barstate.ishistory and close < open 
    strategy.cancel_all()
    isStop := true 

7、strategy.order

strategy.orderFungsi, parameter, dan lain-lain hampir sama denganstrategy.entryKeserasian, perbezaanstrategy.orderFungsi tidak bolehstrategyFungsipyramidingPengaturan parameter memberi kesan, tidak ada had jumlah kali berikutnya.

Parameter:

  • id: boleh difahami sebagai merujuk kepada nama untuk kedudukan dagangan tertentu.
  • direction: jika arah pesanan adalah untuk melakukan lebih (membeli) parameter ini akan dihantarstrategy.longVariabel terbina dalam ini akan dihantar jika anda mahu kosongkan (menjual).strategy.shortIni adalah pembolehubah.
  • qty: menentukan jumlah pesanan, jika parameter ini tidak dihantar, jumlah pesanan secara lalai akan digunakan.
  • when: syarat pelaksanaan, anda boleh menetapkan parameter ini untuk mengawal sama ada operasi bawah perintah semasa akan dicetuskan.
  • limit: Tentukan harga terhad pesanan.
  • stop: harga henti rugi.

Kita gunakan.strategy.orderTidak ada had pada sifat ini, apabila digabungkanstrategy.exitFungsi keluar bersyarat ─ membina skrip yang menyerupai transaksi grid ─ contohnya sangat mudah dan hanya digunakan untuk belajar:

/*backtest
start: 2021-03-01 00:00:00
end: 2022-08-30 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["ZPrecision",0,358374]]
*/

varip beginPrice = -1

if not barstate.ishistory
    if beginPrice == -1 or (math.abs(close - beginPrice) > 1000 and strategy.opentrades == 0) 
        beginPrice := close
    
    for i = 0 to 20
        strategy.order("buy"+i, strategy.long, 0.01, limit=beginPrice-i*200, when=(beginPrice-i*200)<close)
        strategy.exit("coverBuy"+i, "buy"+i, qty=0.01, profit=200)
        
        strategy.order("sell"+i, strategy.short, 0.01, limit=beginPrice+i*200, when=(beginPrice+i*200)>close)
        strategy.exit("coverSell"+i, "sell"+i, qty=0.01, profit=200)

Contoh Strategi

Contoh strategi dalam tutorial ini hanya digunakan untuk pengajaran strategi dan idea reka bentuk strategi panduan, dan tidak membuat sebarang panduan atau cadangan dagangan.

Strategi Indikator Super Trend

strategy("supertrend", overlay=true)

[supertrend, direction] = ta.supertrend(input(5, "factor"), input.int(10, "atrPeriod"))

plot(direction < 0 ? supertrend : na, "Up direction", color = color.green, style=plot.style_linebr)
plot(direction > 0 ? supertrend : na, "Down direction", color = color.red, style=plot.style_linebr)

if direction < 0
    if supertrend > supertrend[2]
        strategy.entry("entry long", strategy.long)
    else if strategy.position_size < 0
        strategy.close_all()
else if direction > 0
    if supertrend < supertrend[3]
        strategy.entry("entry short", strategy.short)
    else if strategy.position_size > 0
        strategy.close_all()

Menggunakan bahasa Pine untuk menulis strategi trend adalah sangat mudah, di sini kita menggunakan indikator trend super untuk merancang strategi pengesanan trend yang mudah. Mari kita menganalisis kod sumber strategi ini.

Mulakan menggunakan kod strategi.strategyFungsi ini melakukan beberapa tetapan mudah:strategy("supertrend", overlay=true), hanya menetapkan tajuk strategi untuk supertrend.overlayParameter ialahtrueKita merancang strategi Pine atau belajar skrip strategi Pine. Pertama kita lihat adalah reka bentuk parameter antara muka strategi, kita melihat sumber "Strategi Petunjuk Super Trend", yang mengandungi beberapa perkara yang telah kita pelajari dalam kursus sebelumnya.inputFungsi

[supertrend, arah] = ta.supertrend(input(5, factor),input.int(10, trPeriod))

inputPanggilan fungsi digunakan secara langsung sebagaita.supertrendParameter fungsi penunjuk digunakan untuk mengira penunjuk supertrend; antara lain:

Fungsi secara lalai menetapkan dua kawalan parameter di antara antara antara muka dasar bahasa Pine, seperti berikut:

img

Jadi anda boleh lihat, nilai lalai pada alat kawalan adalahinputFungsi daninputFungsi barisan (() di sini ialahinput.intFungsi ini boleh digunakan untuk menetapkan pada antara muka strategi.ta.supertrendFungsi parameter. Fungsi indikator supertrend mengira data harga.supertrenddan data satu arah.directionKemudian gunakan.plotGrafik fungsi, perhatikan bahawa ketika menggambar, ia digambar mengikut arah penunjuk supertrend, dan hanya menggambar arah semasa; apabiladirectionPada masa yang sama, trend semasa adalah trend ke atas.directionPada pukul 1 pagi, pasaran sekarang adalah trend ke bawah.plotMenentukan ketika menggambar grafik fungsidirectionLebih besar daripada, kurang daripada 0.

Berikut adalah:if ... else ifLogika adalah penilaian isyarat transaksi, apabila ungkapandirection < 0Ini menunjukkan bahawa pasaran sedang berada di peringkat yang lebih tinggi pada masa ini, jika data harga dalam indikator super trendsupertrendLebih tinggi daripada harga penunjuk supertrend pada dua bar sebelumnya (iaitusupertrend[2],还记得历史操作符引用某个变量历史数据吧Jika anda mempunyai pegangan pada masa ini, panggilan fungsi tunggal ke bawah yang dilakukan pada masa ini akan mengimbangi pegangan sebelum ini, dan kemudian membuka pegangan mengikut arah perdagangan semasa.supertrend > supertrend[2]Jika tidak, saya akan cuba untuk menghidupkan semula.strategy.position_size < 0Jika anda memegang kedudukan kosong, ia akan mencetuskan serangan.strategy.close_all()Fungsi dijalankan, melakukan semua pengetatan.

direction > 0Sama juga ketika berada dalam peringkat trend ke bawah, jika terdapat banyak pemegang saham yang semuanya berdamai, maka syarat-syarat memenuhi.supertrend < supertrend[3]Jika anda ingin melihat gambar di atas, anda perlu melihat gambar di bawah.[3]Apakah yang dimaksudkan oleh ahli strategi, selepas semua, beberapa pasaran seperti pasaran perdagangan kontrak mengambil risiko yang lebih besar daripada mengambil risiko yang lebih besar?

Untukta.supertrendJika anda ingin mengetahui apakah trend yang sedang berlaku, apakah anda ingin mengetahui apakah trend yang sedang berlaku sekarang adalah trend yang sedang meningkat atau sedang menurun?

Malah, penunjuk ini juga boleh dilaksanakan dalam bentuk fungsi tersuai dalam bahasa Pine:

pine_supertrend(factor, atrPeriod) =>
	src = hl2
	atr = ta.atr(atrPeriod)
	upperBand = src + factor * atr
	lowerBand = src - factor * atr
	prevLowerBand = nz(lowerBand[1])
	prevUpperBand = nz(upperBand[1])

	lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
	upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand
	int direction = na
	float superTrend = na
	prevSuperTrend = superTrend[1]
	if na(atr[1])
		direction := 1
	else if prevSuperTrend == prevUpperBand
		direction := close > upperBand ? -1 : 1
	else
		direction := close < lowerBand ? 1 : -1
	superTrend := direction == -1 ? lowerBand : upperBand
	[superTrend, direction]

Fungsi ini adalah sebagai berikut:ta.supertrendAlgoritma yang sama, dan tentu saja data penunjuk yang dikira sama. Dari algoritma fungsi tersuai ini, kita boleh lihat bahawa pentadbiran penunjuk supertrend yang dibina oleh Pine menggunakanhl2Variabel terbina dalam (harga tertinggi, harga minimum ditambah dan kemudian dibahagikan dengan 2, iaitu purata harga tertinggi dan harga minimum) kemudian mengira penunjuk ATR (gelombang) untuk tempoh tertentu berdasarkan parameter atrPeriod; dan kemudian menggunakan hl2 dan ATR untuk membina lintasan.

Kemas kini berdasarkan ungkapan tiga dalam kodlowerBanddanupperBand

    lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
    upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand

lowerBand: Garis bawah, digunakan untuk menentukan sama ada trend menaik berubah; upperBand: Garis atas, digunakan untuk menentukan sama ada trend menaik berubah. LowerBand dan upperBand sentiasa dikira, hanya pada fungsi khusus ini untuk menentukan arah trend semasa.

    else if prevSuperTrend == prevUpperBand
        direction := close > upperBand ? -1 : 1
    else
        direction := close < lowerBand ? 1 : -1

Di sini, kita boleh menilai jika harga pada bar terdahulu adalahprevUpperBand, iaitu garis naik, menunjukkan trend ke bawah pada masa ini.closeLebih daripadaupperBandApabila harga melonjak, ia dianggap sebagai perubahan trend dan berubah menjadi trend menaik.directionVariabel arah ditetapkan sebagai -1 (tren menaik); jika tidak, ia tetap ditetapkan sebagai 1 (tren menurun); jadi anda akan melihat dalam strategi supertren.if direction < 0Apabila keadaan isyarat dipicu, lakukan lebih banyak.direction > 0Apabila keadaan isyarat dipicu, kosongkan.

    superTrend := direction == -1 ? lowerBand : upperBand
    [superTrend, direction]

Akhirnya, berdasarkan arah yang dipilih, data harga dan arah penunjuk supertrend tertentu akan dikembalikan.

Strategi Keseimbangan Dinamik

/*backtest
start: 2021-03-01 00:00:00
end: 2022-09-08 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["v_input_1",4374],["v_input_2",3],["v_input_3",300],["ZPrecision",0,358374]]
*/

varip balance = input(50000, "balance")
varip stocks = input(0, "stocks")

maxDiffValue = input(1000, "maxDiffValue")


if balance - close * stocks > maxDiffValue and not barstate.ishistory
    // more balance , open long 
    tradeAmount = (balance - close * stocks) / 2 / close
    strategy.order("long", strategy.long, tradeAmount)
    balance := balance - tradeAmount * close
    stocks := stocks + tradeAmount
    runtime.log("balance:", balance, ", stocks:", stocks, ", tradeAmount:", tradeAmount)

else if close * stocks - balance > maxDiffValue and not barstate.ishistory
    // more stocks , open short 
    tradeAmount = (close * stocks - balance) / 2 / close
    strategy.order("short", strategy.short, tradeAmount)
    balance := balance + tradeAmount * close
    stocks := stocks - tradeAmount
    runtime.log("balance:", balance, ", stocks:", stocks, ", tradeAmount:", tradeAmount)

plot(balance, title="balance value(quoteCurrency)", color=color.red)
plot(stocks*close, title="stocks value(quoteCurrency)", color=color.blue)

img

img

Kita teruskan dengan mempelajari beberapa contoh reka bentuk strategi bahasa Pine, kali ini kita akan melihat strategi keseimbangan dinamik.BaseCurrencyJumlah (jenis yang diperdagangkan) danQuoteCurrencyJumlah (mata wang) sentiasa melakukan pengolahan imbangan; aset mana yang meningkat harga relatifnya, nilai yang dipegang dalam akaun meningkat dan aset mana yang dijual; jika harga relatif aset tertentu menurun, nilai yang dipegang dalam akaun menurun, anda membeli aset ini. Ini adalah apa yang disebut strategi imbangan dinamik. Sebenarnya strategi imbangan dinamik adalah strategi grid, yang berfungsi dengan baik dalam keadaan bergolak; tetapi dalam keadaan trend, kerugian berterusan diperlukan, menunggu harga kembali untuk mengurangkan kerugian secara perlahan sehingga menguntungkan, tetapi lebih baik dalam strategi imbangan dinamik yang sentiasa dapat menangkap pergerakan bergolak dalam keadaan bergolak.

Kelemahan strategi ini adalah seperti yang ditunjukkan dalam carta pengamatan semula strategi ini, strategi ini mempunyai kerugian yang lebih besar pada peringkat kenaikan (atau kejatuhan) harga besar. Oleh itu, strategi ini baik untuk strategi semasa, tetapi penggunaan masa hadapan memerlukan pengendalian risiko.

Di sini, kita akan melihat strategi reka bentuk kod:

Kami menggunakan reka bentuk yang lebih mudah untuk meniru strategi yang sama.balance(iaitu jumlah aset Kuota Mata Wang) danstocks(iaitu jumlah aset BaseCurrency) maklumat baki. Kami tidak membaca jumlah aset sebenar dalam akaun, kami hanya menggunakan jumlah simulasi untuk mengira pembelian dan penjualan yang sesuai. Kemudian parameter utama yang mempengaruhi strategi imbangan dinamik ini adalahmaxDiffValue, parameter ini adalah kriteria penilaian yang dilakukan untuk menyeimbangkan. Pada harga semasa, hanya harga semasa yang boleh digunakan untuk menilai harga semasa.BaseCurrencydanQuoteCurrencyPerbezaan melebihimaxDiffValuePada masa yang sama, kita perlu melakukan penimbangan, menjual aset yang mahal, membeli aset yang murah, dan menyeimbangkan semula aset.

Isyarat dagangan strategi mesti dipicu pada peringkat BAR masa nyata, jadi syarat dagangan strategi ditetapkan dalam pertimbangan ifnot barstate.ishistory❖ Apabila dihitung berdasarkan harga semasa,balanceNilai melebihistocksMembeli apabila nilai dilakukan. Menjual sebaliknya. Mengemas kini selepas melakukan pernyataan urus niagabalancedanstocksJika anda mempunyai masalah yang sama, anda boleh menukarnya kepada kata ganti, kemudian menunggu untuk ketegangan seterusnya.

Maklumat di atas yang mengandungi harga varieti pada masa permulaan, iaitu harga 1458, jadi saya sengaja menetapkan parameter ini.balanceTetapkan parameter untuk: 4374 ((1458*3)stocksUntuk: 3. Pastikan aset berada dalam keadaan seimbang pada permulaan.

Strategi super trend dengan pengesanan stop loss stop loss

Dalam kelas sebelumnya, kita telah belajarstrategy.exitFungsi keluar kedudukan, yang mempunyai fungsi stop loss stop loss yang tidak kami jelaskan contohnya. Dalam contoh reka bentuk strategi di bahagian ini, kami menggunakanstrategy.exitFungsi pengesanan stop loss untuk mengoptimumkan strategi supertrend.

Pertama, mari kita lihat.strategy.exitParameter penghentian rugi untuk fungsi pengesan:

1、trail_priceParameter: mencetuskan meletakkan tracking Stop Loss atau Stop Loss untuk kedudukan tindakan logik ini (dengan harga yang ditetapkan)


Lebih lanjut