Tutorial Pengenalan Bahasa PINE Kuantitatif Pencipta
Inventor Quantitative Trading Platform menyokong strategi penulisan bahasa Pine, menyokong pengulangan, menjalankan strategi bahasa Pine secara langsung, dan menyokong versi rendah bahasa Pine.Dataran StrategiTerdapat banyak strategi Pine yang dikumpulkan dan dipindahkan.
FMZ bukan sahaja menyokong bahasa Pine, tetapi juga menyokong ciri-ciri gambar yang kuat dalam bahasa Pine. Pelbagai ciri di platform FMZ, alat yang banyak digunakan, pengurusan yang efisien dan mudah, juga meningkatkan kepraktisan Pine. FMZ adalah berdasarkan keserasian dengan bahasa Pine, tetapi juga dengan tahap pengembangan, pengoptimuman, dan pemotongan bahasa Pine.
Di bawah ini adalah beberapa perbezaan yang ketara:
-
1 , Dasar Pin pada FMZ, pengenalan versi pada permulaan kod
//@versiondan bermula dengan kodstrategy、indicatorSentensi tidak dikehendaki ditulis, FMZ tidak menyokongnya buat masa iniimportImporlibraryfungsi.Mungkin anda akan melihat beberapa strategi yang bertuliskan:
pine//@version=5 indicator("My Script", overlay = true) src = close a = ta.sma(src, 5) b = ta.sma(src, 50) c = ta.cross(a, b) plot(a, color = color.blue) plot(b, color = color.black) plotshape(c, color = color.red)Atau seperti ini:
pine//@version=5 strategy("My Strategy", overlay=true) longCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28)) if (longCondition) strategy.entry("My Long Entry Id", strategy.long) shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28)) if (shortCondition) strategy.entry("My Short Entry Id", strategy.short)Di FMZ ia boleh diringkaskan sebagai:
pinesrc = close a = ta.sma(src, 5) b = ta.sma(src, 50) c = ta.cross(a, b) plot(a, color = color.blue, overlay=true) plot(b, color = color.black, overlay=true) plotshape(c, color = color.red, overlay=true)Atau:
pinelongCondition = ta.crossover(ta.sma(close, 14), ta.sma(close, 28)) if (longCondition) strategy.entry("My Long Entry Id", strategy.long) shortCondition = ta.crossunder(ta.sma(close, 14), ta.sma(close, 28)) if (shortCondition) strategy.entry("My Short Entry Id", strategy.short) -
2 , Strategi [script] Sesetengah tetapan yang berkaitan dengan transaksi ditetapkan oleh parameter "Pine Language Transaction Class Repository" pada antara muka FMZ Strategi.
-
Model harga akhir dan model harga masa nyata
Dalam pandangan perdagangan, kita boleh melaluistrategyFungsicalc_on_every_tickParameter untuk menetapkan skrip strategi untuk melaksanakan logik strategi secara langsung setiap kali harga berubah, ketika inicalc_on_every_tickParameter hendaklah ditetapkan sebagaitrue◦ Secara lalaicalc_on_every_tickParameter adalahfalseIaitu, logik strategi dijalankan apabila bar K semasa strategi telah habis sepenuhnya.
Di FMZ, parameter template "Pine Language Exchange Class Repository" boleh diset. -
Pengendalian ketepatan nilai seperti harga, kuantiti pesanan dan lain-lain semasa pelaksanaan strategi diperlukan di FMZ
Dalam pandangan perdagangan kerana hanya boleh melakukan ujian simulasi, tidak ada masalah ketepatan masa pesanan di bursa nyata. Dalam FMZ, anda boleh menjalankan strategi Pin secara nyata. Maka anda memerlukan strategi yang dapat menentukan ketepatan harga jenis perdagangan, ketepatan jumlah pesanan dengan fleksibel. Tetapan ketepatan ini adalah untuk mengawal bilangan kecil data yang berkaitan, untuk mengelakkan data tidak sesuai dengan keperluan pelaporan bursa sehingga tidak dapat melakukan pesanan. -
Kod kontrak jangka masa
Jenis dagangan di FMZ jika kontrak, mempunyai 2 sifat: "pasangan dagangan" dan "kod kontrak". Selain perlu menetapkan pasangan dagangan secara jelas pada masa yang sama, anda juga perlu menetapkan kod kontrak khusus dalam parameter "kod jenis" templat "Pine Language Trading Classroom". Sebagai contoh, kontrak kekal hanya perlu diisiswapKode kontrak untuk melihat sama ada pertukaran yang beroperasi mempunyai kontrak sedemikian. Sebagai contoh, semua kontrak suku tahunan untuk perdagangan boleh diisi di siniquarter。 Kod kontrak ini sepadan dengan kod kontrak berjangka yang ditakrifkan pada dokumen API bahasa Javascript/python/c++ FMZ.。
Tetapan lain seperti jumlah minimum dan jumlah lalai boleh dilihat dalam dokumentasi bahasa Pine mengenaiPerpustakaan pertukaran bahasa PinePengenalan parameter:
-
-
3、
runtime.debug、runtime.log、runtime.errorFungsi FMZ yang diperluaskan, digunakan untuk melakukan debug.FMZ platform telah menambah 3 fungsi untuk debugging.
-
runtime.debug: Fungsi ini biasanya tidak digunakan untuk mencetak maklumat pembolehubah di papan kawalan. -
runtime.logDi dalam log: output │ FMZ PINE mempunyai fungsi khusus │pineruntime.log(1, 2, 3, close, high, ...),可以传多个参数。 -
runtime.errorApabila dipanggil, ia akan menyebabkan ralat semasa operasi dan membawa mesej ralat yang dinyatakan dalam parameter pesan.pineruntime.error(message)
-
-
- sebahagian daripada fungsi gambar yang diperluas
overlayparameter
Fungsi gambar dalam bahasa Pine di FMZ
plot、plotshape、plotcharTambah lagioverlaySokongan parameter yang membolehkan anda menetapkan gambar pada gambar utama atau gambar kecil.overlaysediakantrueGambar di carta utama, set kefalseMenggambar pada subgambar. Membolehkan strategi Pine di FMZ untuk menggambar pada gambar utama dan subgambar pada masa yang sama. - sebahagian daripada fungsi gambar yang diperluas
-
5、
syminfo.mintickMengambil nilai pembolehubah terbina dalamsyminfo.mintickVariabel terbina dalam ditakrifkan sebagai nilai pengukuran minimum untuk varieti semasa.Tawaran Firma/Ujian belakangKeakuratan harga mata wang adalah parameter templat dalam "Pine Language Transaction Classroom" di dalam antara muka untuk mengawal nilai tersebut. Pengaturan ketepatan harga mata wang 2 adalah harga yang tepat pada masa perdagangan ke nombor kedua yang kecil, di mana unit perubahan minimum harga adalah 0.01syminfo.mintickJadi, nilai 0.01 ialah -
- Harga purata dalam FMZ PINE Script adalah harga yang termasuk yuran
Sebagai contoh: harga pesanan adalah 8000, menjual arah, kuantiti 1 tangan ((satu, keping), harga purata selepas urus niaga bukan 8000, kurang daripada 8000 ((biaya termasuk yuran proses) <unk>
Asas Bahasa Pine
Apabila kita mula mempelajari asas bahasa Pine, mungkin kita tidak biasa dengan arahan, kod kod dalam beberapa contoh. Tidak mengapa jika kita tidak faham, kita boleh terlebih dahulu membiasakan diri dengan konsep, memahami tujuan ujian, atau kita boleh menyemak dokumentasi bahasa Pine FMZ untuk melihat arahan. Kemudian ikuti tutorial langkah demi langkah untuk membiasakan diri dengan pelbagai tatabahasa, arahan, fungsi, dan pembolehubah dalaman.
Pelaksanaan model
Pada permulaan pembelajaran bahasa Pine, adalah sangat penting untuk memahami konsep-konsep yang berkaitan seperti proses pelaksanaan skrip bahasa Pine. Strategi bahasa Pine dijalankan berdasarkan carta, yang boleh difahami sebagai satu siri pengiraan dan operasi, yang dijalankan pada carta mengikut urutan masa yang berturut-turut, bermula dari data terdahulu yang telah dimuat.bar_indexMengutip nilai indeks Bar K semasa skrip Pine dijalankan.
pine
plot(bar_index, "bar_index")
plotFungsi ini adalah salah satu fungsi yang akan kita gunakan pada masa akan datang. Ia mudah digunakan, ia adalah untuk melukis garis pada grafik berdasarkan parameter yang kita masukkan, dan data yang kita masukkan adalahbar_index, baris dinamakanbar_indexAnda boleh lihat bahawa bar_index pada Bar pertama adalah 0, dan Bar bertambah 1 ke kanan.
Model pelaksanaan strategi berbeza bergantung kepada tetapan strategi, yang terbahagi kepada收盘价模型dan实时价模型Model harga penutupan, konsep model harga masa nyata telah kami jelaskan sebelum ini.
-
Model Harga Penutupan
Apabila kod strategi dijalankan, kitaran K Bar semasa telah selesai, kitaran K Bar telah selesai apabila K Bar ditutup. Pada masa ini, logik strategi Pine dijalankan sekali lagi, dan isyarat perdagangan yang dicetuskan akan dilaksanakan pada permulaan Bar K Bar berikutnya.
-
Model harga masa nyata
Apabila kod strategi dijalankan, Bar K semasa akan melaksanakan logik strategi Pin setiap kali perubahan berlaku, sama ada ia ditutup atau tidak, dan isyarat perdagangan yang dicetuskan akan dilaksanakan serta-merta.
Apabila strategi bahasa Pine dijalankan dari kiri ke kanan pada carta, Bar K pada carta adalah历史Bardan实时BarOleh:
-
Sejarah Bar
Apabila strategi yang ditetapkan sebagai "Model Harga Saham Nyata" mula dijalankan, semua Bar Bar K pada carta kecuali Bar Bar K di sebelah kanan adalah
历史Bar◯ Logik strategi dalam setiap历史BarHanya sekali sahaja.
Apabila strategi yang ditetapkan sebagai "model harga penutupan" bermula, semua Bar di carta akan历史Bar◯ Logik strategi dalam setiap历史BarHanya sekali sahaja.Pengiraan berdasarkan Bar Sejarah:
Kode strategi dijalankan sekali dalam keadaan tutup Bar Sejarah, kemudian kod strategi diteruskan untuk dijalankan pada Bar Sejarah seterusnya sehingga semua Bar Sejarah dijalankan sekali. -
Bar masa nyata
Apabila strategi dijalankan ke Bar barisan K yang paling kanan, Bar itu adalah Bar masa nyata. Apabila Bar masa nyata ditutup, Bar ini menjadi Bar masa nyata yang telah lalu (berubah menjadi Bar sejarah). Bar masa nyata baru akan dihasilkan di sebelah kanan grafik.
Apabila strategi ditetapkan sebagai "model harga masa nyata" untuk memulakan pelaksanaan, logik strategi akan dijalankan untuk setiap perubahan perdagangan di Bar Masa Nyata.
Bar tidak akan muncul pada carta apabila strategi yang ditetapkan sebagai "model harga penutupan" bermula.Berdasarkan pengiraan Bar secara langsung:
Jika strategi yang ditetapkan sebagai "model harga penutupan" tidak menunjukkan Bar dalam masa nyata, kod strategi hanya dijalankan sekali pada penutupan Bar semasa.
Jika anda menetapkan strategi sebagai "model harga saham sebenar" di Bar masa nyata, pengiraan dan sejarah Bar adalah sama sekali berbeza, setiap perubahan pergerakan di Bar sebenar akan melaksanakan kod strategi. Contohnya, pembolehubah dalamanhigh、low、closeDalam sejarah Bar adalah pasti, dalam masa nyata Bar mungkin setiap kali keadaan berubah nilai-nilai ini akan berubah. Oleh itu, data seperti penunjuk yang dikira berdasarkan nilai-nilai ini juga akan berubah dalam masa nyata. Dalam masa nyata BarcloseIa adalah harga terkini, dan ia adalah harga yang paling murah.highdanlowSentiasa mewakili tertinggi tertinggi dan terendah terendah yang telah dicapai sejak Bar Masa Kini bermula. Variabel terbina dalam ini mewakili nilai akhir ketika Bar Masa Kini terakhir diperbaharui.Mekanisme rollback semasa melaksanakan strategi pada Bar Masa Nyata (model harga masa nyata):
Dalam pelaksanaan Bar secara real-time, setiap iterasi baru strategi yang dijalankan, pembolehubah yang ditakrifkan oleh pengguna yang ditetapkan semula dipanggil rollback. Untuk memahami mekanisme rollback dengan contoh, berikut adalah kod ujian.Notis:
/*backtest ... .. . */Paket itu mengandungi maklumat konfigurasi pengembalian yang disimpan dalam bentuk kod di platform FMZ.
pine/*backtest start: 2022-06-03 09:00:00 end: 2022-06-08 15:00:00 period: 1m basePeriod: 1m exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ var n = 0 if not barstate.ishistory runtime.log("n + 1之前, n:", n, " 当前bar_index:", bar_index) n := n + 1 runtime.log("n + 1之后, n:", n, " 当前bar_index:", bar_index) plot(n, title="n")Kami hanya mengkaji adegan yang dilakukan di Bar Masa Nyata, jadi kami menggunakan
not barstate.ishistoryBatasan ekspresi hanya digunakan untuk mengumpul n pembolehubah pada masa nyata Bar dan digunakan sebelum dan selepas melakukan operasi pengumpulanruntime.logFungsi output maklumat dalam log strategi.plotGaris n yang digambar dapat dilihat ketika strategi berada di Bar Sejarah, n telah menjadi 0. Apabila ia dijalankan ke Bar Masa Nyata, ia mencetuskan operasi n + 1, dan setiap pusingan menjalankan strategi di Bar Masa Nyata, ia menjalankan operasi n + 1. Dari maklumat log, dapat dilihat bahawa setiap pusingan menjalankan semula kod strategi, n telah diset semula ke nilai yang akhirnya diserahkan oleh strategi Bar Masa Nyata sebelumnya.Untuk meringkaskan:
1 , setiap kali anda melakukan update, anda akan menjalankan satu kod strategi.
2. Apabila dijalankan di Bar Masa Nyata, setiap kali kod dasar dijalankan, pembolehubah akan dibalikkan.
3. Apabila dijalankan pada Bar Masa Nyata, pembolehubah dihantar sekali semasa kemas kini penutupan.Oleh kerana data berputar ke belakang, operasi lukisan seperti kurva pada carta juga boleh menyebabkan penggambaran semula, contohnya, jika kita mengubah kod ujian yang baru saja kita buat, ujian cakera:
pinevar n = 0 if not barstate.ishistory runtime.log("n + 1之前, n:", n, " 当前bar_index:", bar_index) n := open > close ? n + 1 : n runtime.log("n + 1之后, n:", n, " 当前bar_index:", bar_index) plot(n, title="n")Kami hanya mengubah ayat ini:
n := open > close ? n + 1 : n, Bar sebenar semasa adalah negatif ((iaitu harga pembukaan lebih tinggi daripada harga penutupan) hanya kepada n ditambah 1 . Anda boleh melihat dalam carta pertama ((saat A) kerana harga pembukaan pada masa itu lebih tinggi daripada harga penutupan ((sinis) jadi n ditambah 1, grafik n menunjukkan nilai 5 . Kemudian perubahan tren, harga dikemas kini seperti yang ditunjukkan dalam carta kedua ((saat B). Apabila harga pembukaan adalah lebih rendah daripada harga penutupan ((sinis), n nilai berguling dan tidak ditambah 1 . -
Konteks pembolehubah dalam fungsi
Di bawah ini kita akan mengkaji pembolehubah dalam fungsi bahasa Pine. Berdasarkan penerangan di beberapa tutorial Pine, pembolehubah dalam fungsi berbeza dengan pembolehubah di luar fungsi:
Sejarah pembolehubah siri yang digunakan dalam fungsi Pine dibuat dengan setiap panggilan berturut-turut fungsi tersebut. Jika fungsi tidak dipanggil pada setiap lajur yang dijalankan dalam skrip, ini akan menyebabkan perbezaan antara nilai sejarah dalaman dan luar siri dalam blok tempatan fungsi. Oleh itu, jika fungsi tidak dipanggil pada setiap lajur, siri yang menggunakan nilai indeks yang sama yang dirujuk di dalam dan luar fungsi tidak akan merujuk pada titik sejarah yang sama.
Tidak mengapa, kita akan faham dengan menggunakan kod ujian yang dijalankan di FMZ:
pine/*backtest start: 2022-06-03 09:00:00 end: 2022-06-08 15:00:00 period: 1m basePeriod: 1m exchanges: [{"eid":"Bitfinex","currency":"BTC_USD"}] */ f(a) => a[1] f2() => close[1] oneBarInTwo = bar_index % 2 == 0 plotchar(oneBarInTwo ? f(close) : na, title = "f(close)", color = color.red, location = location.absolute, style = shape.xcross, overlay = true, char = "A") plotchar(oneBarInTwo ? f2() : na, title = "f2()", color = color.green, location = location.absolute, style = shape.circle, overlay = true, char = "B") plot(close[2], title = "close[2]", color = color.red, overlay = true) plot(close[1], title = "close[1]", color = color.green, overlay = true)Skrin tayangan semula
Kod ujian adalah lebih mudah, terutamanya untuk mengkaji data yang dikutip dalam dua cara, iaitu:
f(a) => a[1]danf2() => close[1]。-
f(a) => a[1]Cara menggunakan parameter, fungsi kembali pada akhira[1]。 -
f2() => close[1]Menggunakan pembolehubah terbina dalam:close, fungsi yang dikembalikan pada akhirclose[1]。
[]Simbol digunakan untuk operasi rujukan kepada nilai sejarah pembolehubah siri data, close[1] iaitu merujuk kepada data harga penutupan pada Bar sebelum harga penutupan semasa.-
plotchar(oneBarInTwo ? f(close) : na, title = "f(close)", color = color.red, location = location.absolute, style = shape.xcross, overlay = true, char = "A")
Lukis satu aksara A<unk>, warna merah, apabila oneBarInTwo adalah benar, dan letakkannya (di atas sumbu Y) adalah:f(close)Nilai yang dikembalikan -
plotchar(oneBarInTwo ? f2() : na, title = "f2()", color = color.green, location = location.absolute, style = shape.circle, overlay = true, char = "B")
Lukis satu aksara di B<unk>, warna hijau, apabila oneBarInTwo adalah benar, dan letaknya (di atas sumbu Y) adalah:f2()Nilai yang dikembalikan -
plot(close[2], title = "close[2]", color = color.red, overlay = true)
Garis yang digambar, berwarna merah, diletakkan di (atas sumbu Y) sebagai:close[2]Iaitu harga penutupan pada Bar barisan 2 barisan depan Bar (atau 2 barisan kiri Bar). -
plot(close[1], title = "close[1]", color = color.green, overlay = true)
Garis yang digambar berwarna hijau, diletakkan di (atas sumbu Y) sebagai:close[1]Iaitu harga penutupan pada Bar Bar nombor 1 ke kiri.
Sketsa berjalan melalui strategi pengesanan semula boleh dilihat, walaupun fungsi yang digunakan untuk tanda gambar A
f(a) => a[1]Fungsi yang digunakan untuk menandakan dan melukis Bf2() => close[1]Semua digunakan.[1] untuk merujuk kepada data sejarah dalam siri data, tetapi kedudukan penanda "A" dan "B" dalam carta adalah sama sekali berbeza. Penanda "A" sentiasa berada di garisan merah, iaitu kod dalam strategiplot(close[2], title = "close[2]", color = color.red, overlay = true)Pada garis yang digariskan, data yang digunakan ialahclose[2]。Sebabnya ialah ia diindekskan melalui Bar Bar K, iaitu pembolehubah terbina dalam.
bar_indexHitung sama ada lukisan "A" dan "B" tanda. "A" dan "B" tanda tidak dicat pada setiap Bar K (dicat apabila memanggil fungsi pengiraan) fungsif(a) => a[1]Nilai yang dirujuk dengan cara ini akan bersesuaian dengan fungsi jika fungsi tidak dipanggil pada setiap Bar.f2() => close[1]Nilai yang dirujuk dengan cara ini adalah berbeza walaupun kedua-dua kaedah digunakan.[1] seperti indeks yang sama) <unk> -
-
Beberapa fungsi terbina dalam perlu dikira pada setiap Bar untuk mengira hasilnya dengan betul
Sebagai contoh mudah:
pineres = close > close[1] ? ta.barssince(close < close[1]) : -1 plot(res, style = plot.style_histogram, color=res >= 0 ? color.red : color.blue)Kami akan memanggil kod fungsi.
ta.barssince(close < close[1])Tulis dalam satu operator tigacondition ? value1 : value2Ini membawa kepada kesesakan dalamclose > close[1]Apabila anda memanggil fungsi ta.barssince.ta.barssinceFungsi ini dikira dari kali terakhirclose < close[1]Bilangan baris K semasa pembentukan. Apabila fungsi ta.barssince dipanggil, ia adalah close > close[1], iaitu harga penutupan semasa lebih besar daripada harga penutupan Bar sebelumnya, apabila fungsi ta.barssince dipanggil dengan syarat close < close[1] tidak ditubuhkan, dan tidak ada lokasi yang terakhir ditubuhkan.ta.barssince: Apabila dipanggil, fungsi ini akan mengembalikan na。 jika ia tidak pernah memenuhi syarat sebelum baris K semasa.
Seperti yang ditunjukkan dalam rajah:
Jadi, apabila kita melukis, kita hanya melukis data apabila nilai res ialah ((-1) <unk>).
Untuk mengelakkan masalah ini, kita hanya menggunakan
ta.barssince(close < close[1])Panggilan fungsi diambil dari pengendali trivial dan ditulis di luar cawangan syarat yang mungkin. Ia membolehkan ia menjalankan pengiraan pada setiap Bar baris K.a = ta.barssince(close < close[1]) res = close > close[1] ? a : -1 plot(res, style = plot.style_histogram, color=res >= 0 ? color.red : color.blue)
Jadual masa
Konsep urutan masa sangat penting dalam bahasa Pine, dan merupakan konsep yang perlu kita fahami ketika kita belajar bahasa Pine. Suruhan masa bukanlah jenis tetapi struktur asas untuk menyimpan nilai berturut-turut pembolehubah dari masa ke masa. Kita tahu skrip Pine adalah berdasarkan carta, dan yang paling asas yang ditunjukkan dalam carta adalah carta K. Suruhan masa di mana setiap nilai dikaitkan dengan garis masa K Bar.openmerupakan pembolehubah dalaman dalam bahasa Pine, yang mempunyai struktur untuk menyimpan setiap K-line Bar sebagai urutan masa untuk harga bukaan. Ia boleh difahami sebagaiopenStruktur urutan masa ini mewakili harga pembukaan semua Bar Bar K semasa K semasa dari Bar pertama yang bermula hingga Bar yang dijalankan oleh skrip semasa. Jika K semasa adalah kitaran 5 minit, maka kita merujuk dalam kod strategi Pine (atau menggunakan)openIa adalah harga pembukaan K-bar pada masa pelaksanaan semasa menggunakan kod strategi.[]Operator <unk> digunakan apabila strategi Pine dijalankan pada Bar baris Kopen[1]Menunjukkan rujukanopenHarga pembukaan Bar Bar K yang terdahulu yang dijalankan oleh skrip semasa dalam urutan masa ((iaitu harga pembukaan K Bar yang terakhir dalam kitaran K).
-
Variabel dalam urutan masa sangat mudah untuk dikira
Kami menggunakan fungsi terbina dalam.ta.cumContohnya:ta.cum Cumulative (total) sum of `source`. In other words it's a sum of all elements of `source`. ta.cum(source) → series float RETURNS Total sum series. ARGUMENTS source (series int/float) SEE ALSO math.sumKod ujian:
pinev1 = 1 v2 = ta.cum(v1) plot(v1, title="v1") plot(v2, title="v2") plot(bar_index+1, title="bar_index")Terdapat banyak yang serupa
ta.cumFungsi terbina dalam seperti ini boleh memproses data dalam siri masa secara langsung, sepertita.cumIa adalah untuk menambah nilai-nilai yang sepadan pada setiap K-bar, dan kemudian kita menggunakan grafik untuk memudahkan pemahaman.bar_index IDEV1 IDEV2 IDEV
| - | - | - | - |
Strategi ini berjalan pada garis K Bar 0 dan 1 dan 1 dan 1
Strategi ini berjalan pada K-bar 1, 1, 2, 3.
Strategi ini berjalan pada K-bar 2 dan 1 dan 3
|...|...|...|...|
Strategi berjalan pada N+1 akar K Bar dan N+1 akar dan N+1 akarAnda dapat melihat bahawa v1, v2 dan bar_index adalah struktur urutan masa, dengan data yang sesuai di setiap Bar. Kod ujian ini tidak membezakan antara "model harga masa nyata" atau "model harga penutupan" hanya untuk menunjukkan Bar sebenar di carta. Untuk mengukur kelajuan, kami menggunakan "model harga penutupan" untuk menguji semula.
Kerana v1 adalah 1 pada setiap bar.
ta.cum(v1)Fungsi ini dijalankan pada baris pertama K Bar, dan hasilnya ialah 1, dengan nilai kepada pembolehubah v2。
Apabilata.cum(v1)Apabila dilakukan pada Bar K baris kedua, sudah ada 2 Bar K baris ((bar_index bagi baris pertama adalah 0, bar_index bagi baris kedua adalah 1), maka hasilnya adalah 2, dan nilai diberikan kepada v2, dan seterusnya. Sebenarnya dapat dilihat bahawa v2 adalah bilangan Bar baris K dalam grafik, kerana indeks baris Kbar_indexIa akan meningkat dari 0.bar_index + 1Ia sebenarnya adalah bilangan bar bar K.v2danbar_indexIa adalah satu perjumpaan.Saya juga boleh menggunakan
ta.cumFungsi terbina dalam mengira jumlah harga penutupan semua Bar pada carta semasa, dan ia hanya boleh ditulis sebagai berikut:ta.cum(close), apabila strategi dijalankan ke Bar Waktu Nyata di sebelah kananta.cum(close)Hasil yang dikira adalah jumlah harga penutupan semua Bar di carta (jika tidak berjalan ke sebelah kanan, hanya ditambah kepada Bar semasa).Variabel pada urutan masa juga boleh dihitung menggunakan pengendali, seperti kod:
ta.sma(high - low, 14)Menggunakan pembolehubah dalaman.high(K Bar harga tertinggi) tolaklow(K Line Bar Minimum Harga), penggunaan terakhirta.smaFungsi mencari nilai purata. -
Hasil panggilan fungsi akan meninggalkan kesan nilai dalam urutan masa
v1 = ta.highest(high, 10)[1] v2 = ta.highest(high[1], 10) plot(v1, title="v1", overlay=true) plot(v2, title="v2", overlay=true)Kod ujian ini dijalankan semasa pengukuran semula dan dapat dilihat
v1danv2Nilai yang sama, garis yang digambar pada carta juga berlainan sepenuhnya. Hasil yang dikira oleh panggilan fungsi akan meninggalkan jejak nilai dalam urutan masa, seperti kodta.highest(high, 10)[1]Antara mereka:ta.highest(high, 10)Hasil yang dikira dari panggilan fungsi juga boleh digunakan[1] untuk merujuk kepada nilai sejarahnya.ta.highest(high, 10)Hasilnya ialahta.highest(high[1], 10)Oleh itu.ta.highest(high[1], 10)danta.highest(high, 10)[1]Harga yang sama.Output maklumat yang disahkan dengan fungsi gambar lain:
a = ta.highest(close, 10)[1] b = ta.highest(close[1], 10) plotchar(true, title="a", char=str.tostring(a), location=location.abovebar, color=color.red, overlay=true) plotchar(true, title="b", char=str.tostring(b), location=location.belowbar, color=color.green, overlay=true)Anda dapat melihat nilai-nilai pembolehubah a dan pembolehubah b dalam urutan masa yang dipaparkan di atas dan di bawah Bar masing-masing. Anda boleh menyimpan kod lukisan ini semasa pembelajaran, kerana maklumat yang dikeluarkan pada carta mungkin sering diperlukan untuk diperhatikan semasa ujian dan percubaan.
Struktur skrip
Struktur umum
Pada bahagian permulaan tutorial ini, kami telah meringkaskan beberapa perbezaan antara penggunaan bahasa Pine di FMZ dan bahasa Pine di Trading View.indicator()、strategy()Dan, tidak disokong buat masa inilibrary()❚ Sudah tentu untuk bersesuaian dengan skrip Pine versi terdahulu, strategi ditulis seperti://@version=5,indicator(),strategy()Ia juga boleh. Sesetengah tetapan dasar boleh diletakkan di bawahstrategy()Tetapan parameter dalam fungsi.
<version>
<declaration_statement>
<code>
<version>Maklumat kawalan versi boleh diabaikan.
Nota
Bahasa Pine//Sebagai nota satu baris, kerana bahasa Pine tidak mempunyai nota berbilang baris./**/Untuk nota berbilang baris.
Kod
Garis yang tidak memberi komen atau arahan kompilator dalam skrip adalah pernyataan, yang mewujudkan algoritma skrip. Pernyataan boleh menjadi salah satu daripada ini.
- Pengisytiharan pemboleh ubah
- Penjenamaan semula pemboleh ubah
- Pengisytiharan fungsi
- Panggilan fungsi terbina dalam, panggilan fungsi yang ditakrifkan pengguna
if,for,whileatauswitchStruktur lain
Perkataan boleh disusun dengan pelbagai cara
- Sesetengah ungkapan boleh dinyatakan dengan satu baris, seperti kebanyakan deklarasi pembolehubah, yang hanya mengandungi satu baris panggilan fungsi atau deklarasi fungsi baris tunggal. Yang lain, seperti struktur, selalu memerlukan lebih banyak baris, kerana mereka memerlukan satu blok tempatan.
- Perkataan dalam skop global skrip (iaitu, bahagian yang tidak tergolong dalam blok tempatan) tidak boleh dianggap sebagai
空格atau制表符(Kunci tab) bermula。 Karakter pertama mereka juga mestilah karakter pertama baris tersebut。 Baris yang bermula pada kedudukan pertama baris, menjadi sebahagian daripada skop global skrip mengikut definisi。 - Struktur atau pernyataan fungsi berbilang baris sentiasa memerlukan
local block。 Satu blok tempatan mesti dikurangkan ke dalam satu tanda pengenal atau empat ruang kosong ((jika tidak, ia akan diuraikan sebagai kod berturut-turut baris sebelumnya, iaitu dihakimi sebagai kesinambungan baris sebelumnya), dan setiap blok tempatan mentakrifkan ruang lingkup tempatan yang berbeza。 - Pelbagai ungkapan tunggal boleh disusun dalam satu baris dengan menggunakan tanda koma ((,) sebagai pemisah.
- Satu baris boleh mengandungi komen atau hanya komen.
- Baris juga boleh dibungkus ((terus dalam pelbagai baris) <unk>)
Sebagai contoh, termasuk tiga blok lokal, satu dalam deklarasi fungsi tersuai, dan dua menggunakan struktur if dalam deklarasi pembolehubah, seperti berikut:
pine
indicator("", "", true) // 声明语句(全局范围),可以省略不写
barIsUp() => // 函数声明(全局范围)
close > open // 本地块(本地范围)
plotColor = if barIsUp() // 变量声明 (全局范围)
color.green // 本地块 (本地范围)
else
color.red // 本地块 (本地范围)
runtime.log("color", color = plotColor) // 调用一个内置函数输出日志 (全局范围)
Kod ganti baris
Baris panjang boleh dibahagikan kepada beberapa baris, atau "dibungkus". Baris yang dibungkus mesti menyusut ke dalam apa-apa jumlah ruang, asalkan ia bukan kelipatan 4 (perbatasan ini digunakan untuk menyusut ke dalam blok tempatan).
pine
a = open + high + low + close
Ia boleh dibungkus sebagai (perhatikan bahawa jumlah ruang yang dikurangkan dalam setiap baris bukanlah kelipatan 4):
pine
a = open +
high +
low +
close
Panggilan plot ((() yang panjang boleh dibungkus dalam ▽.
pine
close1 = request.security(syminfo.tickerid, "D", close) // syminfo.tickerid 当前交易对的日线级别收盘价数据系列
close2 = request.security(syminfo.tickerid, "240", close) // syminfo.tickerid 当前交易对的240分钟级别收盘价数据系列
plot(ta.correlation(close, open, 100), // 一行长的plot()调用可以被包装
color = color.new(color.purple, 40),
style = plot.style_area,
trackprice = true)
Perkataan dalam deklarasi fungsi yang ditakrifkan oleh pengguna juga boleh dibungkus. Namun, kerana blok tempatan secara gramatikal mesti bermula dengan pengurangan (- 4 ruang kosong atau 1 tanda kerja), apabila membahagikannya ke baris seterusnya, bahagian lanjutan perkataannya mesti bermula dengan pengurangan lebih daripada satu (- tidak sama dengan kelipatan 4 ruang kosong). Contohnya:
pine
test(c, o) =>
ret = c > o ?
(c > o+5000 ?
1 :
0):
(c < o-5000 ?
-1 :
0)
a = test(close, open)
plot(a, title="a")
Pengenal dan operator
Penjenamaan
Sebelum kita memahami variabel, kita perlu memahami konsep tanda pengenal tanda baca.fungsidanPembolehubahNama yang digunakan untuk menamakan pembolehubah (variabel, fungsi)fungsiSeperti yang anda akan pelajari di tutorial seterusnya, kita mulakan dengan mempelajari kod pengenalan lembu, <unk>。
-
- Penanda mesti ditulis dengan huruf besar
(A-Z)atau huruf kecil(a-z)Huruf atau garisan bawah(_)Permulaan, sebagai aksara pertama pengiktirafan.
- Penanda mesti ditulis dengan huruf besar
- 2 , karakter pertama selepas pengenal bolehAksara、Garis bawahatauNombor。
-
- Nama pengenal adalah huruf besar dan kecil.
Sebagai contoh, nama-nama berikut:
pine
fmzVar
_fmzVar
fmz666Var
funcName
MAX_LEN
max_len
maxLen
3barsDown // 错误的命名!使用了数字字符作为标识符的开头字符
Seperti kebanyakan bahasa pengaturcaraan, bahasa Pine juga mempunyai cadangan penulisan. Ia biasanya disyorkan untuk menamakan pengenal:
- 1 , semua huruf besar digunakan untuk menamakan malar.
-
- PenggunaanPeraturan HumpbackNama untuk pengenal yang lain.
pine
// 命名变量、常量
GREEN_COLOR = #4CAF50
MAX_LOOKBACK = 100
int fastLength = 7
// 命名函数
zeroOne(boolValue) => boolValue ? 1 : 0
Pengendali
Pengendali adalah beberapa simbol pengendali dalam bahasa pengaturcaraan yang digunakan untuk membina ungkapan, dan ungkapan adalah peraturan pengiraan yang dirancang untuk tujuan pengiraan tertentu ketika kita menulis strategi. Pengendali dalam bahasa Pine diklasifikasikan mengikut fungsi sebagai:
Pengendali penambahan nilai, pengendali aritmatika, pengendali perbandingan, pengendali logik,? : Pengendali triad[]Operator rujukan sejarah:
Pengendali algebra*Sebagai contoh, untuk membezakan jenis soalan yang dikembalikan oleh pengendali bahasa Pine di Trading View, terdapat kod ujian berikut:
pine
//@version=5
indicator("")
lenInput = input.int(14, "Length")
factor = year > 2020 ? 3 : 1
adjustedLength = lenInput * factor
ma = ta.ema(close, adjustedLength) // Compilation error!
plot(ma)
Ini adalah salah satu sebab mengapa skrip ini terkompilasi semasa dijalankan di Trading View.adjustedLength = lenInput * factorSelepas kita tambah, hasilnya ialahseries intJenis (seri), bagaimanapunta.emaParameter kedua fungsi tidak menyokong jenis ini. Tetapi tidak ada sekatan ketat seperti itu pada FMZ, kod di atas boleh berfungsi dengan baik.
Di bawah ini, kita akan melihat penggunaan pelbagai pengendali.
Operator penempatan nilai
Terdapat dua jenis pengendali nilai:=、:=Kami juga melihat beberapa contoh di bahagian awal tutorial ini.
=Operator digunakan untuk memberi nilai kepada pembolehubah apabila ia diwujudkan atau diisytiharkan.=Initialization, deklarasi, dan penugasan akan bermula dengan nilai tersebut pada setiap Bar selepasnya. Ini adalah deklarasi yang sah:
a = close // 使用内置变量赋值给a
b = 10000 // 使用数值赋值
c = "test" // 使用字符串赋值
d = color.green // 使用颜色值赋值
plot(a, title="a")
plot(b, title="b")
plotchar(true, title="c", char=str.tostring(c), color=d, overlay=true)
Notisa = closePernyataan penyerahan, di mana setiap Bar mempunyai a sebagai harga penutupan Bar semasa ((close) ⋅ variabel lainb、c、dIa tidak berubah, boleh diuji dalam sistem maklum balas di FMZ, dan hasilnya boleh dilihat dari gambar.
:=Ia digunakan untuk memberi nilai semula kepada pembolehubah yang sedia ada. Ia boleh difahami sebagai penggunaan:=Operator digunakan untuk mengubah nilai pembolehubah yang telah diisytiharkan dan diinisialisasi.
Jika digunakan:=Operator memberi nilai kepada pembolehubah yang tidak dimulakan atau diisytiharkan akan menyebabkan ralat, seperti:
pine
a := 0
Oleh itu,:=Operator penempatan biasanya digunakan untuk penempatan semula nilai kepada pembolehubah yang sedia ada, seperti:
pine
a = close > open
b = 0
if a
b := b + 1
plot(b)
menilai jikaclose > open(iaitu BAR semasa adalah garis bujur), dan variabel a adalah nilai sebenar ((true)) ≠ akan melaksanakan kod dalam blok tempatan pernyataan ifb := b + 1, menggunakan pengendali nilai:=Berikan nilai semula kepada b, tambah 1 ◦ dan kemudian gunakan fungsi plot untuk melukis nilai pembolehubah b pada setiap BAR dalam urutan masa, bersambung ke dalam garis ◦
Adakah kita berfikir bahawa jika ada bar bar, b akan terus bertambah 1? Tentu tidak, di sini kita tidak menggunakan kata kunci untuk menyatakan b, dan menginisialisasi sebagai 0.b=0Jadi anda boleh lihat bahawa hasil dari kod ini adalah untuk menetapkan semula b kepada 0 setiap kali jika a adalah nilai sebenar, maka ia sesuai.close > openJadi, apabila anda menjalankan kod pada pusingan ini, b akan menambah 1, apabila anda menggambar fungsi plot, b akan menjadi 1, tetapi apabila anda menjalankan kod pada pusingan berikutnya, b akan diberi nilai semula sebagai 0.
Berkenaan dengan operator penyerahan nilai, dua kata kunci perlu diperluaskan:var、varip
-
var
Sebenarnya, kata kunci ini telah kita lihat dan gunakan dalam tutorial sebelum ini, tetapi tidak dibincangkan secara terperinci.
var adalah kata kunci untuk pembahagian dan inisialisasi sekali-per-kali. Secara amnya, semantik pemberian nilai pembolehubah tanpa kata kunci var menyebabkan nilai pembolehubah ditutup setiap kali data dikemas kini. Sebaliknya, apabila menggunakan kata kunci var untuk pembahagian pembolehubah, mereka masih boleh menyimpan status mereka walaupun data dikemas kini
Kita masih menggunakan contoh ini, tetapi apabila kita memberi nilai kepada b
varKata kunci:pinea = close > open var b = 0 if a b := b + 1 plot(b)varKata kunci membolehkan pembolehubah b hanya melaksanakan penugasan pertama pada mulanya, dan tidak akan menetapkan semula b kepada 0 pada setiap kali logik dasar dijalankan, jadi garis yang digambar pada masa berjalan dapat dilihat b iaitu jumlah bar yang muncul pada garis BAR semasa K semasa.Variabel dalam deklarasi var boleh ditulis dalam blok kod, bukan sahaja dalam skala global, seperti contoh ini:
pinestrategy(overlay=true) var a = close var b = 0.0 var c = 0.0 var green_bars_count = 0 if close > open var x = close b := x green_bars_count := green_bars_count + 1 if green_bars_count >= 10 var y = close c := y plot(a, title = "a") plot(b, title = "b") plot(c, title = "c")Variabel 'a' mengekalkan harga penutupan tiang pertama dalam siri.
Peubah 'b' mengekalkan harga penutupan batang harga aluminium hijau pertama dalam siri.
Variable 'c' mengekalkan harga penutupan untuk ketupat hijau ketupat kesepuluh dalam siri. -
varip
varipIni adalah kali pertama kita melihat kata kunci ini, dan kita boleh lihat deskripsi kata kunci ini:varip ((var intrabar persist) adalah kata kunci yang digunakan untuk mengalokasikan dan menginisialisasi pembolehubah sekali gus. Ia serupa dengan kata kunci var, tetapi pembolehubah yang menggunakan varip menyatakan mengekalkan nilainya di antara kemas kini K-line dalam masa nyata.
Adakah lebih sukar untuk difahami? Tidak mengapa, kita akan menerangkannya dengan contoh, ia akan mudah difahami.
strategy(overlay=true) // 测试 var varip var i = 0 varip ii = 0 // 将策略逻辑每轮改变的i、ii打印在图上 plotchar(true, title="ii", char=str.tostring(ii), location=location.abovebar, color=color.red) plotchar(true, title="i", char=str.tostring(i), location=location.belowbar, color=color.green) // 每轮逻辑执行都给i、ii递增1 i := i + 1 ii := ii + 1Kod ujian ini berlainan untuk model harga penutupan dan model harga masa nyata:
Model harga masa nyata:
Ingatkah anda bahawa kita telah memaparkan bahawa strategi yang kita jalankan sebelum ini mempunyai fasa BAR yang bersejarah dan fasa BAR yang sebenar?var、varipVariabel yang diisytiharkani、iiPada setiap pusingan kod strategi, operasi peningkatan akan dilakukan. Oleh itu, kita dapat melihat bahawa setiap angka yang ditunjukkan pada garis KBAR hasil pengukuran kembali adalah peningkatan 1. Apabila fasa K baris sejarah berakhir, fasa K baris masa nyata bermula.i := i + 1danii := ii + 1Ia akan dilaksanakan sekali. Perbezaannya ialah ii akan diubah setiap kali. Walaupun ia akan diubah setiap kali, ia akan kembali kepada nilai sebelumnya pada setiap pusingan logik pelaksanaan strategi (ingatkan mekanisme penggulungan yang kami jelaskan pada bab "Pelaksanaan Model") sehingga KBAR berjalan dan ia akan mengemas kini nilai i yang ditentukan (iaitu, ia tidak akan kembali kepada nilai sebelumnya pada setiap pusingan logik pelaksanaan strategi).Model harga penutupan:
Oleh kerana model harga penutupan adalah setiap garis K BAR berjalan, satu logik strategi dijalankan. Oleh itu, dalam model harga penutupan, fasa K-bar sejarah dan fasa K-bar masa nyata, var, varip menyatakan peningkatan prestasi yang sama dalam contoh di atas, adalah setiap garis K-BAR meningkat 1 <unk>.
Operator algebra
| Pengendali | menggambarkan |
|---|---|
| + | Penambahan |
| - | Pengurangan |
| * | Perkalian |
| / | Penghapusan undang-undang |
| % | Cari contoh |
+、-Operator boleh digunakan sebagai operator binari, atau sebagai operator satuan. Operator aljabar lain hanya boleh digunakan sebagai operator binari, jika digunakan sebagai operator satuan akan membuat kesalahan.
1 , pengendali aritmatika kedua-dua belah adalah jenis nilai, hasilnya adalah jenis nilai, jenis bulat atau nombor titik terapung bergantung kepada hasil operasi.
2. Operator jika nombor operasinya adalah string.+, hasil pengiraan adalah string, nilai akan ditukarkan kepada bentuk string, dan kemudian string disusun bersama-sama. Jika ia adalah pengendali algebra lain, ia akan cuba untuk menukarkan string ke nilai dan kemudian beroperasi.
3. Jika terdapat nombor operasi na, maka hasil pengiraan adalah nilai sifar na, dan NaN akan dipaparkan apabila ia dicetak pada FMZ.
pine
a = 1 + 1
b = 1 + 1.1
c = 1 + "1.1"
d = "1" + "1.1"
e = 1 + na
runtime.log("a:", a, ", b:", b, ", c:", c, ", d:", d, ", e:", e)
// a: 2 , b: 2.1 , c: 11.1 , d: 11.1 , e: NaN
Bahasa Pine di FMZ sedikit berbeza dengan bahasa Pine di Trading View, bahasa Pine di FMZ tidak terlalu ketat untuk keperluan jenis pembolehubah. Contohnya:
pine
a = 1 * "1.1"
b = "1" / "1.1"
c = 5 % "A"
plot(a)
plot(b)
plot(c)
FMZ boleh dijalankan, tetapi pada pandangan perdagangan, ia akan melaporkan ralat jenis. Apabila operasi di kedua-dua belah pengendali aritmatika adalah string, sistem akan mengubah string menjadi nilai nombor dan kemudian dikira. Jika string bukan nilai tidak dapat dikira, hasil operasi sistem akan menjadi nilai kosong na.
Operator perbandingan
Operator perbandingan adalah operator binari.
| Pengendali | menggambarkan |
|---|---|
| < | kurang daripada |
| > | Lebih besar daripada |
| <= | kurang daripada sama dengan |
| >= | Lebih besar daripada sama dengan |
| == | Persamaan |
| != | Ketidaksamaan |
Contoh ujian:
pine
a = 1 > 2
b = 1 < 2
c = "1" <= 2
d = "1" >= 2
e = 1 == 1
f = 2 != 1
g = open > close
h = na > 1
i = 1 > na
runtime.log("a:", a, ", b:", b, ", c:", c, ", d:", d, ", e:", e, ", f:", f, ", g:", g, ", h:", h, ", i:", i)
// a: false , b: true , c: true , d: false , e: true , f: true , g: false , h: false , i: false
Seperti yang anda lihat, pengendali perbandingan sangat mudah digunakan, tetapi ia juga merupakan pengendali yang paling banyak digunakan dalam penulisan strategi. Ia boleh digunakan untuk membandingkan nilai dan juga untuk membandingkan pembolehubah dalaman, seperticlose、opentunggu.
Seperti pengendali operasi, pada FMZ terdapat perbezaan dengan Pin dari Trading View, FMZ tidak mempunyai jenis keperluan yang sangat ketat, jadi pernyataan seperti itud = "1" >= 2 Pada FMZ tidak akan membuat kesalahan, ia akan menukarkan rentetan ke nilai nombor sebelum perbandingan dijalankan. Pada Trading View, ia akan membuat kesilapan.
Operator logik
| Pengendali | Nombor kod | menggambarkan |
|---|---|---|
| Tidak | not | Operator unit, bukan operasi |
| dan | and | Operator binari, dengan (dan) operasi |
| atau | or | Operator binari, atau operasi |
Bercakap tentang operator logik, kita mesti bercakap tentang jadual nilai sebenar. Seperti yang kita belajar di sekolah tinggi, hanya di sini kita menguji dan belajar dalam sistem feedback:
pine
a = 1 == 1 // 使用比较运算符构成的表达式,结果为布尔值
b = 1 != 1
c = not b // 逻辑非操作符
d = not a // 逻辑非操作符
runtime.log("测试逻辑操作符:and", "#FF0000")
runtime.log("a:", a, ", c:", c, ", a and c:", a and c)
runtime.log("a:", a, ", b:", b, ", a and b:", a and b)
runtime.log("b:", b, ", c:", c, ", b and c:", b and c)
runtime.log("d:", d, ", b:", b, ", d and b:", d and b)
runtime.log("测试逻辑操作符:or", "#FF0000")
runtime.log("a:", a, ", c:", c, ", a or c:", a or c)
runtime.log("a:", a, ", b:", b, ", a or b:", a or b)
runtime.log("b:", b, ", c:", c, ", b or c:", b or c)
runtime.log("d:", d, ", b:", b, ", d or b:", d or b)
runtime.error("stop")
Untuk mengelakkan sistem pengesanan daripada terjejas oleh pencetakan maklumat yang berterusan, kami menggunakanruntime.error("stop")Perkataan selepas melakukan pencetakan sekali lagi, ia akan membuang kesilapan yang luar biasa untuk menghentikan pengukuran, dan kemudian anda boleh melihat maklumat output, dan anda dapat melihat bahawa kandungan cetakan dan jadual nilai sebenar sebenarnya sama.
Pengendali triad
Menggunakan pengendali triad? : Ekspresi trivial yang digabungkan dengan nombor operasicondition ? valueWhenConditionIsTrue : valueWhenConditionIsFalseKita sudah biasa dengan ungkapan tiga, operator tiga, yang bermaksud bahawa terdapat tiga operasi.
condition ? valueWhenConditionIsTrue : valueWhenConditionIsFalseAntara lain:conditionIaitu, jika nilai untuk ungkapan yang benar ialah:valueWhenConditionIsTrueJikaconditionEkspresinya ialahvalueWhenConditionIsFalse。
Walaupun tidak banyak kegunaan, contoh yang mudah untuk ditunjukkan:
pine
a = close > open
b = a ? "阳线" : "阴线"
c = not a ? "阴线" : "阳线"
plotchar(a, location=location.abovebar, color=color.red, char=b, overlay=true)
plotchar(not a, location=location.belowbar, color=color.green, char=c, overlay=true)
Tidak mengapa jika anda terjumpa tanda salib! ungkapan tiga dimensi juga boleh disematkan, seperti yang telah kita lakukan dalam tutorial sebelumnya.
pine
a = close > open
b = a ? math.abs(close-open) > 30 ? "阳线" : "十字星" : math.abs(close-open) > 30 ? "阴线" : "十字星"
c = not a ? math.abs(close-open) > 30 ? "阴线" : "十字星" : math.abs(close-open) > 30 ? "阳线" : "十字星"
plotchar(a, location=location.abovebar, color=color.red, char=b, overlay=true)
plotchar(not a, location=location.belowbar, color=color.green, char=c, overlay=true)
Ia sama dengan meletakkancondition ? valueWhenConditionIsTrue : valueWhenConditionIsFalseDalamvalueWhenConditionIsTrue、valueWhenConditionIsFalse, juga menggunakan ungkapan triad lain sebagai gantinya.
Operator sejarah
Menggunakan operator sejarah[], merujuk kepada nilai sejarah pada urutan masa. Nilai sejarah ini adalah nilai pada baris K BAR sebelum baris K BAR semasa skrip dijalankan.[]Operator digunakan selepas panggilan pembolehubah, ungkapan, dan fungsi.[]Nombor dalam tanda kurung ini adalah perpindahan data sejarah dari garis BAR K semasa. Sebagai contoh, jika saya ingin merujuk harga penutupan garis BAR K yang lalu, saya akan menulis:close[1]。
Kami telah melihat tulisan seperti ini dalam kursus-kursus sebelumnya:
pine
high[10]
ta.sma(close, 10)[1]
ta.highest(high, 10)[20]
close > nz(close[1], open)
[]Operator ini hanya boleh digunakan sekali pada nilai yang sama, jadi ia adalah salah, dan ia akan melakukan kesalahan:
pine
a = close[1][2] // 错误
Mungkin anda lihat di sini, sesetengah pelajar akan berkata, operator[]Ia digunakan untuk struktur siri, ia kelihatan seperti struktur siri (series) dan array!
Di bawah ini, kita akan menggunakan contoh untuk menerangkan perbezaan antara siri dalam bahasa Pine (series) dan array.
pine
strategy("test", overlay=true)
a = close
b = close[1]
c = b[1]
plot(a, title="a")
plot(b, title="b")
plot(c, title="c")
Walaupun berkataa = close[1][2]Saya tidak tahu apa-apa tentang apa yang anda katakan, tetapi saya tidak mahu bercakap tentang apa yang anda katakan.
pine
b = close[1]
c = b[1]
Tidak ada salahnya untuk menulisnya secara berasingan, jika anda memahaminya mengikut susun atur yang biasa.b = close[1]Selepas nilai, b sepatutnya menjadi nilai, tetapic = b[1]b masih boleh digunakan untuk merujuk nilai sejarah lagi dengan menggunakan pengendali sejarah. Seperti yang dapat dilihat, konsep siri dalam bahasa Pine tidak semudah arsip. Ia boleh difahami sebagai nilai sejarah pada Bar yang lebih dekat (yang diberikan kepada b), b juga merupakan struktur urutan masa (time series), yang boleh terus merujuk nilai sejarahnya.
Kita boleh menarik grafik ke kiri dan melihat bahawa pada baris pertama K, nilai b dan c adalah nilai kosong ((na) <unk>). Itu kerana apabila skrip dijalankan pada baris pertama K BAR, tidak ada nilai sejarah yang merujuk satu atau dua kitaran ke hadapan, ia tidak wujud. Oleh itu, kita perlu sentiasa berhati-hati ketika menulis strategi, sama ada nilai kosong akan dirujuk ketika merujuk data sejarah, jika tidak berhati-hati menggunakan nilai kosong akan menyebabkan pelbagai perbezaan pengiraan, dan mungkin mempengaruhi masa nyata.na、nzFungsi terbina dalam untuk menghakiminz、naFungsi, ingat di bab mana?) yang menangani keadaan yang kosong, contohnya:
pine
close > nz(close[1], open) // 当引用close内置变量前一个BAR的历史值时,如果不存在,则使用open内置变量
Ini adalah rawatan yang mungkin merujuk kepada nilai sifar ((na)).
Keutamaan pengendali
Kita telah mempelajari banyak pengendali dalam bahasa Pine, yang membentuk ungkapan melalui pelbagai kombinasi dan operasi. Jadi, bagaimana keutamaan operasi ini semasa mengira dalam ungkapan? Seperti operasi empat baris yang kita pelajari ketika kita pergi ke sekolah, ada penggandaan dengan pengurangan keutamaan penggandaan, dan kemudian pengurangan penambahan.
| Keutamaan | Pengendali |
|---|---|
| 9 | [] |
| 8 | Operator satuan ``` + 、- dan non `` |
| 7 | *、/、% |
| 6 | Operator binari +、 - |
| 5 | >、<、>=、<= |
| 4 | ==、!= |
| 3 | and |
| 2 | or |
| 1 | ?: |
Bahagian ungkapan yang mempunyai keutamaan yang tinggi dijalankan terlebih dahulu, dan jika keutamaan yang sama, ia dijalankan dari kiri ke kanan. Jika anda ingin memaksa sebahagian daripada ungkapan untuk dijalankan terlebih dahulu, anda boleh menggunakan()Membungkus ungkapan yang perlu dikendalikan terlebih dahulu.
Pembolehubah
Pengisytiharan pemboleh ubah
Kita telah mempelajari konsep tanda pengenal tanda, tanda pengenal tanda adalah nama yang diberikan kepada suatu variabel sebagai nama bagi suatu variabel. Jadi, ia adalah tanda pengenal nilai yang disimpan. Jadi bagaimana untuk mendeklarasikan suatu variabel? Dan apa peraturan yang ada untuk mendeklarasikan variabel?
-
Model pengisytiharan:
Terdapat tiga jenis mod pengisytiharan pembolehubah iaitu:- Menggunakan kata kunci
var。 - Gunakan kata kunci
varip。 - Tidak menulis apa-apa.
var、varipKata kunci sebenarnya telah kita pelajari di bab "Operator Penentuan Nilai" sebelum ini, dan tidak akan dibahaskan di sini. Jika model pengisytiharan pembolehubah tidak menulis apa-apa, contohnya:i = 1Sebenarnya, kita telah bercakap sebelum ini, pembolehubah yang dinyatakan dan diberi nilai, dilaksanakan pada setiap baris KBAR. - Menggunakan kata kunci
-
taip
Bahasa Pine di FMZ tidak ketat terhadap keperluan jenis, dan biasanya boleh diabaikan. Walau bagaimanapun, untuk menyesuaikan diri dengan strategi skrip di Trading View, pembolehubah boleh dinyatakan dengan jenis. Contohnya:int i = 0 float f = 1.1Jenis dalam Trading View adalah lebih ketat, dan anda akan mendapat kesalahan jika anda menggunakan kod berikut dalam Trading View:
baseLine0 = na // compile time error! -
Penjenamaan
Pengiktirafan ialah nama pembolehubah, nama pengiktirafan telah dibincangkan dalam bab sebelumnya, boleh dilihat semula: https://www.fmz.com/bbs-topic/9390#标识符
Untuk meringkaskan, pernyataan terhadap satu pemboleh ubah boleh ditulis sebagai:
// [<declaration_mode>] [<type>] <identifier> = value
声明模式 类型 标识符 = 值
Di sini, operator penambahan nilai digunakan:=Berikan nilai kepada pembolehubah semasa pengisytiharan pembolehubah. Nilai yang diberikan boleh berupa senar, nilai, ungkapan, panggilan fungsi, dan sebagainya.if、 for、whileatauswitchStruktur dll ((kata kunci struktur, penggunaan frasa kami akan menjelaskan secara terperinci dalam pelajaran seterusnya, sebenarnya kita telah belajar dalam pelajaran sebelumnya pemberian frasa if yang mudah, anda boleh melihat semula)
Di sini kita akan fokus pada fungsi input, fungsi yang sering kita gunakan dalam merancang dan menulis strategi. Ia juga merupakan fungsi yang sangat penting dalam merancang strategi.
Fungsi input:
input函数,参数defval、title、tooltip、inline、group
Fungsi input pada FMZ dan pada Trading View agak berbeza, tetapi fungsi ini digunakan sebagai input yang diberikan kepada parameter strategi. Di bawah ini kita akan menerangkan penggunaan fungsi input pada FMZ dengan contoh:
pine
param1 = input(10, title="参数1名称", tooltip="参数1的描述信息", group="分组名称A")
param2 = input("close", title="参数2名称", tooltip="参数2的描述信息", group="分组名称A")
param3 = input(color.red, title="参数3名称", tooltip="参数3的描述信息", group="分组名称B")
param4 = input(close, title="参数4名称", tooltip="参数4的描述信息", group="分组名称B")
param5 = input(true, title="参数5名称", tooltip="参数5的描述信息", group="分组名称C")
ma = ta.ema(param4, param1)
plot(ma, title=param2, color=param3, overlay=param5)
Pada FMZ, fungsi input akan secara automatik melukis kawalan yang digunakan untuk menetapkan parameter dasar. Kawalan yang disokong pada FMZ kini mempunyai kotak input angka, kotak input teks, kotak bawah, dan pilihan nilai bul. Ia juga boleh menetapkan komponen parameter dasar dan maklumat teks isyarat untuk menetapkan parameter.
Di sini, kita akan membincangkan beberapa parameter utama fungsi input:
- defval: nilai lalai untuk pilihan parameter dasar yang ditetapkan oleh fungsi input, menyokong pembolehubah, nilai, dan senar terbina dalam bahasa Pine
- title: nama parameter yang ditunjukkan oleh polisi pada antara muka polisi pada cakera keras/pemeriksaan semula.
- tooltip: isyarat parameter dasar, apabila tetikus diletakkan di atas parameter dasar, ia akan memaparkan maklumat teks yang ditetapkan untuk parameter ini.
- group: nama kumpulan parameter dasar yang boleh diberikan kepada kumpulan parameter ∂.
Selain pengisytiharan dan penekanan pembolehubah individu, bahasa Pine juga menyatakan satu set pembolehubah dan penekanan nilai:
[变量A,变量B,变量C] = 函数 或者 ```if```、 ```for```、```while```或```switch```等结构
Yang paling biasa ialah kita menggunakanta.macdApabila fungsi mengira penunjuk MACD, kerana penunjuk MACD adalah penunjuk berbilang baris, tiga set data dikira. Oleh itu, ia boleh ditulis sebagai:
pine
[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 menggunakan kod di atas untuk melukis grafik MACD dengan mudah, bukan hanya fungsi terbina dalam yang dapat mengembalikan banyak pembolehubah, fungsi tersuai yang ditulis juga dapat mengembalikan banyak data.
pine
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)
Penggunaan struktur seperti if sebagai pemberian nilai kepada pelbagai pembolehubah juga serupa dengan fungsi tersuai di atas, yang berminat juga boleh cuba.
[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 Syarat
Beberapa fungsi tidak boleh ditulis dalam blok kod tempatan cabang bersyarat, terutamanya beberapa fungsi berikut:
barcolor(), fill(), hline(), indicator(), plot(), plotcandle(), plotchar(), plotshape()
Trading View akan mengkompilasi laporan kesalahan. Di FMZ, sekatan tidak begitu ketat, tetapi juga disyorkan untuk mengikuti peraturan yang ditulis di Trading View. Sebagai contoh, walaupun tidak melaporkan kesalahan di FMZ, tetapi tidak disyorkan untuk menulis sedemikian.
pine
strategy("test", overlay=true)
if close > open
plot(close, title="close")
else
plot(open, title="open")
Pernyataan if
Contohnya:
pine
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)
Nota: Ekspresi yang digunakan untuk menilai, mengembalikan nilai Boolean. Perhatikan bahawa hanya boleh ada satu cabang Else. Semua cabang ekspresi tidak benar, dan jika tidak ada cabang Else, ia akan mengembalikan na.
pine
x = if close > open
close
plot(x, title="x")
Oleh kerana apabila K bar BAR adalah negatif, iaitu apabila close < open, if ungkapan selepas pernyataan adalah false, maka blok kod tempatan untuk if tidak dilaksanakan. Pada masa ini juga tidak ada cabang else, jika pernyataan akan kembali na. . . . . . . .
Kata ganti
Perkataan switch juga merupakan perkataan bercabang yang direka untuk melaksanakan laluan yang berbeza mengikut keadaan tertentu. Perkataan switch secara amnya mempunyai beberapa titik pengetahuan utama seperti berikut:
1 , kata ganti boleh dikembalikan nilai seperti kata if.
2. Tidak seperti kata ganti dalam bahasa lain, apabila melaksanakan struktur suis, hanya satu blok tempatan dalam kodnya yang dilaksanakan, jadi pengisytiharan putus tidak diperlukan (iaitu tidak perlu menulis kata kunci seperti break).
3. Setiap cabang switch boleh menulis satu blok kod tempatan, dan baris terakhir blok kod tempatan ini adalah nilai yang dikembalikan (ia boleh menjadi satu subset nilai). Jika tidak ada cabang yang dipotong blok kod tempatan yang dilaksanakan, ia akan dikembalikan.
4. Ekspresi dalam struktur suis, boleh menulis rentetan, pembolehubah, ungkapan atau panggilan fungsi.
5. switch membolehkan anda menentukan nilai pulangan yang digunakan sebagai nilai lalai apabila tiada keadaan lain dalam struktur.
Terdapat dua jenis switch, dan kita akan lihat contoh-contohnya dan bagaimana ia digunakan.
1 dengan ungkapanswitchContohnya:
pine
// 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 telah belajar fungsi input, dan di sini kita akan belajar dua fungsi yang serupa dengan input:input.string、input.intfungsi.
input.stringIa juga boleh digunakan untuk menghantar semula string.input.intFungsi ini digunakan untuk mengembalikan nilai integer.optionsCara menggunakan parameter.optionsParameter boleh dihantar ke dalam sebuah array yang terdiri daripada nilai yang boleh dipilih.options=["EMA", "SMA", "RMA", "WMA"]danoptions=[5, 10, 20](Perhatikan bahawa satu adalah jenis senar dan satu adalah jenis nilai) Oleh itu, kawalan pada antara muka dasar tidak perlu memasukkan nilai tertentu, tetapi ia menjadi kotak bawah untuk memilih pilihan yang disediakan dalam parameter pilihan.
Func merupakan sebuah string yang berfungsi sebagai ungkapan switch (yang boleh berupa variabel, panggilan fungsi, atau ungkapan) untuk menentukan cabang mana dalam switch yang akan dijalankan. Jika func tidak dapat disamakan dengan ungkapan pada cabang manapun dalam switch (yang setara), maka blok kod cabang default akan dijalankan.runtime.error("error")Fungsi menyebabkan strategi untuk membuang pengecualian berhenti.
Dalam kod ujian kami di atas, kami tidak menyertakan runtime.error selepas baris terakhir dalam blok kod cabang lalai switch[Kod seperti na, na] untuk mengkompatibelkan nilai pulangan, di trading view perlu mempertimbangkan masalah ini, jika jenis tidak sesuai akan memberi kesalahan. Tetapi di FMZ kerana tidak ada jenis yang dikehendaki secara ketat, kod keserasian ini boleh diabaikan. Oleh itu, di FMZ tidak perlu mempertimbangkan keserasian jenis nilai pulangan if, switch branch.
pine
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 berlaku pada FMZ, tetapi berlaku pada pandangan perdagangan. Kerana jenis if yang dikembalikan oleh cabang tidak selaras.
- Tidak bersuara
switch
Mari kita lihat.switchPenggunaan lain ialah menulis tanpa ungkapan.
pine
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 menunjukkan bahawa switch akan memadankan blok kod tempatan yang benar dengan syarat percabangan. Secara amnya, syarat percabangan yang diikuti oleh pernyataan switch mestilah saling bertentangan. Maksudnya, dalam contoh ini, up dan down tidak boleh sama-sama benar.up = close > open // up = close < open Tukarkan ke dalam notis, ulangi dan lihat hasilnya. Anda akan mendapati bahawa cabang switch hanya dapat menjalankan cabang pertama. Selain itu, anda perlu berhati-hati untuk tidak menulis panggilan fungsi di dalam cabang switch, fungsi tidak dapat dipanggil pada setiap BAR yang mungkin menyebabkan beberapa masalah pengiraan data.switch"Dalam contoh ini, cabang pelaksanaan ditetapkan dan tidak akan berubah semasa operasi strategi".)
Struktur kitaran
untuk frasa
返回值 = for 计数 = 起始计数 to 最终计数 by 步长
语句 // 注释:语句里可以有break,continue
语句 // 注释:最后一条语句为返回值
Perkataan for sangat mudah digunakan, kerana loop for akhirnya boleh mengembalikan satu nilai (() atau mengembalikan beberapa nilai untuk[a, b, c] seperti) 。 seperti yang dinyatakan di atas dalam kod palsu yang memberi nilai kepada kedudukan "nilai pulangan". 。 untuk kata-kata yang diikuti oleh "pengiraan" pembolehubah untuk mengawal jumlah kali pusingan, merujuk nilai lain dan sebagainya. 。 "pengiraan" pembolehubah yang diberikan nilai sebagai "pengiraan awal" sebelum permulaan pusingan, dan kemudian meningkat mengikut "langkah" tetapan, apabila "pengiraan" pembolehubah lebih besar daripada "pengiraan akhir" pusingan berhenti.
digunakan dalam kitaran forbreakKata kunci: Apabila dilakukanbreakSelepas itu, kitaran berhenti.
digunakan dalam kitaran forcontinueKata kunci: Apabila dilakukancontinueSelepas itu, loop akan mengabaikan.continueKod seterusnya, menjalankan kitaran seterusnya secara langsung. Perkataan for mengembalikan nilai yang dikembalikan semasa pelaksanaan kitaran terakhir. Jika tidak ada pelaksanaan kod, mengembalikan nilai kosong.
Di bawah ini adalah contoh ringkas:
pine
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")
untuk ... dalam perenggan
for ... inPerkataan ini mempunyai dua bentuk, yang ditunjukkan oleh kod palsu berikut:
返回值 = for 数组元素 in 数组
语句 // 注释:语句里可以有break,continue
语句 // 注释:最后一条语句为返回值
返回值 = for [索引变量, 索引变量对应的数组元素] in 数组
语句 // 注释:语句里可以有break,continue
语句 // 注释:最后一条语句为返回值
Perbezaan utama antara kedua-dua bentuk ini adalah yang diikuti oleh kata kunci for, iaitu menggunakan satu variabel sebagai rujukan kepada unsur-unsur array. Satu lagi adalah menggunakan struktur subset yang mengandungi variabel indeks, unsur-unsur array untuk rujukan. Yang lain adalah peraturan nilai kembali, menggunakan peraturan seperti break, teruskan dan kitaran for.
pine
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")
Gunakan indeks apabila ia diperlukanfor [i, ele] in testArrayPenulisan
Penggunaan kitaran
Apabila anda boleh menggunakan fungsi terbina dalam yang disediakan oleh bahasa Pine untuk melakukan beberapa pengiraan logik berputar, anda boleh menggunakan struktur berputar untuk menulisnya secara langsung, atau anda boleh menggunakan fungsi terbina dalam untuk memprosesnya. Kami akan memberikan dua contoh.
1 , mengira nilai purata
Apabila anda menggunakan reka bentuk struktur kitaran:
pine
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, kami menggunakan for untuk menambah pusingan dan kemudian mengira nilai purata.
Hitung garis purata dengan menggunakan fungsi terbina dalam:
pine
plot(ta.sma(close, length), title="ta.sma", overlay=true)
Fungsi terbina dalamta.smaUntuk mengira nilai rata-rata, jelas lebih mudah untuk menggunakan fungsi terbina dalam untuk mengira rata-rata. Hasil yang dikira adalah sama sekali sama seperti yang dapat dilihat dalam perbandingan pada carta.
- Penjumlahan
Atau gunakan contoh di atas.
Apabila anda menggunakan reka bentuk struktur kitaran:
pine
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)
Anda boleh menggunakan fungsi terbina dalam untuk mengira jumlah semua elemen dalam array dengan menggunakan loop.array.sumUntuk mengira.
Secara langsung menggunakan fungsi terbina dalam untuk mengira penjumlahan:
pine
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)
Data yang dikira dapat dilihat dengan menggunakan gambar plot yang dipaparkan dalam grafik.
Jadi, jika anda boleh menggunakan fungsi terbina dalam untuk melakukan semua ini, mengapa anda perlu merancang kitaran?
- Untuk beberapa operasi, perhitungan.
2 , kembali ke sejarah, contohnya, cari berapa banyak titik tinggi masa lalu yang lebih tinggi daripada titik tinggi BAR semasa. Oleh kerana titik tinggi BAR semasa hanya diketahui pada BAR yang dijalankan oleh skrip, satu kitaran diperlukan untuk kembali pada masa dan menganalisis BAR masa lalu. - Apabila fungsi terbina dalam bahasa Pine tidak dapat menyelesaikan pengiraan BAR yang lalu.
Perkataan sementara
whilePerkataan ini membolehkan kod bagi bahagian kitaran dijalankan sehingga syarat penghakiman dalam struktur while adalah false (false) <unk>
返回值 = while 判断条件
语句 // 注释:语句里可以有break,continue
语句 // 注释:最后一条语句为返回值
Peraturan lain untuk while serupa dengan kitaran for, baris terakhir blok kod tempatan kitaran adalah nilai pulangan, yang boleh mengembalikan beberapa nilai. Apabila "kondisi kitaran" menjalankan kitaran sebagai masa yang benar, dan berhenti kitaran apabila keadaan adalah palsu. Anda juga boleh menggunakan kata putus, teruskan dalam kitaran.
Saya akan tunjukkan dengan menggunakan contoh perhitungan garis rata:
pine
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)
Anda dapat melihat bahawa penggunaan while loop juga sangat mudah, dan anda juga dapat merancang beberapa logik pengiraan yang tidak dapat digantikan dengan fungsi terbina dalam, seperti pengiraan pangkat kali:
pine
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 dan definisi array dalam bahasa pengaturcaraan yang lain adalah serupa. Array dalam bahasa Pine adalah sebuah array berdimensi. Array biasanya digunakan untuk menyimpan satu siri data yang berturut-turut. Array di mana data tunggal yang disimpan dipanggil elemen array, jenis elemen ini boleh menjadi: integer, float, string, nilai warna, nilai bul.[]Ia perlu digunakanarray.get()danarray.set()Fungsi 。 elemen-elemen dalam array diindeks mengikut urutan iaitu elemen pertama dalam array diindeks 0, dan elemen seterusnya diindeks dengan peningkatan 1。
Kami menggunakan kod mudah untuk menerangkan:
pine
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
gunaarray<int> a、float[] bArray yang diisytiharkan atau hanya menyatakan satu pembolehubah boleh diberikan kepada array, contohnya:
pine
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")
Penggunaan umum untuk inisialisasi pembolehubah arrayarray.newdanarray.fromTerdapat banyak fungsi lain dalam bahasa Pine yang berkaitan dengan jenis yang serupa dengan fungsi array.new:array.new_int()、array.new_bool()、array.new_color()、array.new_string()tunggu.
Kata kunci var juga boleh berfungsi dengan mod pengisytiharan array, menggunakan kata kunci var pengisytiharan array hanya diinisialisasi pada BAR pertama. Kita melihat dengan contoh:
pine
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")
Anda dapat melihat bahawa perubahan dalam a terus ditetapkan, tanpa perlu ditukar semula. B pula diinisialisasi pada setiap BAR.barstate.islastUntuk masa nyata, hanya satu elemen yang akan dicetak, iaitu nilai 0 <unk>.
Membaca dan menulis elemen dalam array
Gunakan array.get untuk mendapatkan elemen yang menentukan kedudukan indeks dalam array, gunakan array.set untuk mengubah elemen yang menentukan kedudukan indeks dalam array.
Argumen pertama array.get ialah array yang akan diproses, dan argumen kedua ialah indeks yang ditetapkan.
Parameter pertama array.set adalah array yang akan diuruskan, parameter kedua adalah indeks yang ditetapkan, dan parameter ketiga adalah elemen yang akan ditulis.
Sebagai contoh, perhatikan contoh mudah ini:
pine
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 menginisialisasi warna asas hijau, mengisytiharkan dan menginisialisasi satu array untuk menyimpan warna, dan kemudian memberikan nilai warna dengan ketelusan yang berbeza (menggunakan fungsi color.new). Dengan mengira jarak BAR semasa dari nilai tertinggi dalam 100 pusingan pusingan, gred warna dikira.
Menjelajah unsur-unsur
Bagaimana untuk mengembara melalui sebuah array, kita boleh menggunakan pernyataan for/for in/while yang telah kita pelajari sebelum ini.
pine
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")
pine
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")
pine
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 cara ini mempunyai hasil yang sama.
Array boleh diisytiharkan dalam skop global skrip, atau diisytiharkan dalam skop tempatan fungsi atau cabang if
Sumber data sejarah
Untuk penggunaan elemen dalam array, kaedah berikut adalah setara, kita dapat melihat dengan contoh berikut, kita dapat menggambar dua kumpulan garis pada carta, dua baris dalam setiap kumpulan, dan nilai dua baris dalam setiap kumpulan adalah sama.
pine
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 penambahan dan penyingkiran
- Fungsi yang berkaitan dengan operasi penambahan dalam susunan:
array.unshift()、array.insert()、array.push()。
- Fungsi yang berkaitan dengan penghapusan dalam susunan:
array.remove()、array.shift()、array.pop()、array.clear()。
Kami menggunakan contoh berikut untuk menguji fungsi penambahan dan penghapusan dalam array tersebut.
pine
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")
Menambah dan Menghapuskan Aplikasi: Array sebagai Queue
Dengan menggunakan array, dan beberapa fungsi penambahan dan penghapusan dari array, kita boleh membina struktur data "array". Array boleh digunakan untuk mengira purata bergerak harga tick, dan mungkin ada pelajar yang bertanya: Kenapa kita perlu membina struktur array?
Kuantiti adalah struktur yang sering digunakan dalam bidang pengaturcaraan. Kuantiti mempunyai ciri-ciri seperti:
Unsur-unsur yang masuk ke dalam barisan pertama, keluar barisan pertama.
Ini memastikan bahawa data yang terdapat dalam barisan adalah data terkini, dan panjang barisan tidak akan berkembang tanpa had (kod yang berkembang tanpa had hanya boleh ditulis pada waktu tengah hari, kerana ia boleh menjadi masalah pada waktu pagi dan petang).
Contoh berikut kami menggunakan struktur beratur untuk merekodkan harga setiap tick, mengira purata bergerak pada tahap tick, dan kemudian membandingkannya dengan purata bergerak pada tahap K-line 1 minit.
pine
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 kita menyatakan a, kita menggunakan kata kunci untuk menyatakanvaripOleh itu, setiap perubahan harga akan direkodkan dalam a.
Fungsi pengiraan dan pengendalian argumen
Mengira fungsi yang berkaitan:
array.avg()Cari nilai purata bagi semua elemen dalam susunan.array.min()Cari unsur terkecil dalam susunan.array.max()Cari unsur terbesar dalam susunan.array.stdev()Cari perbezaan piawai bagi semua unsur dalam susunan.array.sum()Cari jumlah semua unsur dalam array.
Fungsi yang berkaitan dengan operasi:
array.concat()Gabungkan atau sambungkan dua array.
array.copy()Menyalin array.
array.joinMenghubungkan semua elemen dalam array ke dalam satu senar.
array.sort()Urutan mengikut urutan naik atau turun.
array.reverse()Array berbalik.
array.slice()Potong Array.
array.includes()Elemen penghakiman
array.indexof()Mengembalikan indeks yang pertama kali muncul apabila nilai parameter dimasukkan. Jika nilai itu tidak ditemui, kembali -1
array.lastindexof()Cari nilai yang muncul terakhir.
Contoh ujian fungsi berkaitan pengiraan arisan:
pine
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 pengiraan array yang lebih biasa digunakan.
Contoh fungsi yang berkaitan dengan operasi:
pine
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 tersuai. Secara umum, fungsi tersuai dalam bahasa Pine mempunyai peraturan berikut:
- Semua fungsi ditakrifkan dalam skop global skrip. Tidak boleh mendeklarasikan fungsi dalam fungsi lain.
- Tidak membenarkan fungsi memanggil dirinya sendiri dalam kodnya sendiri.
- Pada asasnya, semua bahasa PINE mempunyai fungsi grafik yang terbina dalam.
barcolor()、 fill()、 hline()、plot()、 plotbar()、 plotcandle()) tidak boleh dipanggil dalam fungsi tersuai. - Fungsi boleh ditulis dalam bentuk baris tunggal, baris berbilang. Nilai yang dikembalikan dalam ayat terakhir adalah nilai yang dikembalikan oleh fungsi semasa, dan nilai yang dikembalikan boleh dikembalikan dalam bentuk unsur.
Dalam tutorial sebelumnya, kita telah menggunakan fungsi tersuai, seperti fungsi tersuai yang direka dalam satu baris:
pine
barIsUp() => close > open
Fungsi ini mengembalikan sama ada BAR semasa adalah cahaya matahari.
Fungsi tersuai yang direka untuk pelbagai baris:
pine
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 kita buat sendiri dengan fungsi tersuai.
Juga, anda boleh mengembalikan contoh fungsi tersuai untuk dua pembolehubah:
pine
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 laju, garis perlahan, dua indikator EMA rata-rata.
Fungsi terbina dalam
Fungsi terbina dalam boleh dengan mudah diFMZ PINE ScriptPencarian di sini.
Fungsi terbina dalam bahasa Pine dikelaskan:
1 , fungsi pengendalian senarstr.Siri.
2 fungsi pengendalian nilai warnacolor.Siri.
3 , fungsi input parameterinput.Siri.
4. Fungsi pengiraan penunjukta.Siri.
5. Fungsi grafikplot.Siri.
6. Fungsi pemprosesanarray.Siri.
7. Fungsi berkaitan transaksistrategy.Siri.
8., Fungsi berkaitan operasi matematikmath.Siri.
9 , fungsi lain ((pemprosesan masa, bukan plot siri fungsi lukisan grafik,request.Fungsi siri, fungsi pemprosesan jenis, dan lain-lain).
Fungsi urus niaga
strategy.Fungsi siri adalah fungsi yang sering kita gunakan dalam merancang strategi, yang berkaitan dengan fungsi dan strategi untuk menjalankan operasi perdagangan semasa ia dijalankan.
1、strategy.entry
strategy.entryFungsi adalah fungsi perintah yang lebih penting apabila kita menulis strategi, beberapa parameter yang lebih penting adalah:id, direction, qty, whentunggu.
parameter:
id: boleh difahami sebagai nama pertama yang diberikan kepada kedudukan perdagangan tertentu untuk rujukan. Boleh merujuk kepada id ini untuk membatalkan, mengubah suai pesanan, dan mendatarkan kedudukan.directionParameter ini akan diteruskan jika arah pesanan adalah melakukan lebih banyak (atau membeli)strategy.longVariabel ini akan dihantar kepada anda jika anda ingin menjual.strategy.shortVariabel ini ialah:qty: Tentukan jumlah pesanan, jika anda tidak menghantar parameter ini, anda akan menggunakan jumlah pesanan lalai.whenKeadaan pelaksanaan: anda boleh menentukan parameter ini untuk mengawal sama ada operasi perintah semasa ini akan dicetuskan.limitTentukan harga yang terhad untuk pesanan.stop: Harga Hentikan Kerosakan.
strategy.entryPerincian pelaksanaan fungsistrategyPengendalian tetapan parameter semasa panggilan fungsi juga boleh dilakukan melalui"Parameter modem perpustakaan kelas pertukaran bahasa Pine"Untuk lebih terperinci mengenai kawalan tetapan, kawalan parameter modem perpustakaan kelas transaksi bahasa Pine, lihat dokumentasi di pautan tersebut.
Saya ingin berkongsi dengan anda tentang topik ini.strategyDalam fungsi,pyramiding、default_qty_valueParameter <unk> diuji dengan kod berikut:
pine
/*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 adalah untuk seting semula, untuk merekodkan maklumat seperti masa seting semula pada masa itu, untuk memudahkan debug, bukan kod strategi.
Dalam kod:strategy(title = "open long example", pyramiding = 3, default_qty_value=0.1, overlay=true)Apabila kita menetapkanpyramidingApabila parameternya adalah 3, maka kita boleh setkan 3 kali perdagangan dalam arah yang sama. Jadi dalam contoh ini, 4 kali.strategy.entryOperasi perintah berikut tidak dilaksanakan.default_qty_valueParameter adalah 0.1, jadi ID yang dilambangkan sebagai long1strategy.entryPergerakan perintah seterusnya ditetapkan secara lalai sebagai 0.1.strategy.entryFungsi ini dipanggil dengan fungsi yang kita tentukan.directionadalahstrategy.longOleh itu, setiap pesanan yang dibuat pada masa ujian balasan adalah dengan bayaran.
Perhatian dalam kodstrategy.entry("long3", ...Operasi perintah berikut dipanggil dua kali, untuk ID yang sama: <unk>long3<unk>strategy.entryOperasi perintah bawah tidak berjaya, panggilan keduastrategy.entryFungsi untuk mengubah pesanan ID ini: ((Data yang ditunjukkan semasa ujian pengulangan juga dapat melihat bahawa pesanan harga terhad ini telah diubah untuk 0.3)). Sebagai contoh lain, jika ID pertama kali diperdagangkan untuk pesanan 3<unk>, teruskan dengan menggunakan ID yang diperdagangkan untuk 3<unk>strategy.entryJika fungsi ini dipesan, maka kedudukan pesanan akan terkumpul pada ID<unk>long3<unk>
2、strategy.close
strategy.closeFungsi ini digunakan untuk kedudukan kosong yang menentukan ID kedudukan masuk. Parameter utama adalah:id,when,qty,qty_percent。
parameter:
idIni adalah ID masuk yang diperlukan untuk melakukan setoran, yang kami gunakan.strategy.entryID yang ditetapkan apabila fungsi pesanan masuk dibuka.whenSyarat pelaksanaan:qty: Bilangan simpanan kosong.qty_percentPeratusan saham kosong.
Untuk mengetahui lebih lanjut mengenai fungsi ini, lihat contoh berikut:
Dalam kod/*backtest ... */Ini adalah maklumat konfigurasi semasa FMZ.COM International Station Retest, anda boleh menghapus, menetapkan pasaran, jenis, dan jangka masa yang anda perlukan untuk diuji.
pine
/*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
Strategi ujian menunjukkan bahawa tiga kali berturut-turut mula melakukan masuk berganda, ID masuk masing-masing adalah <unk>long1<unk>, dan kemudian menggunakanstrategy.closeHasil yang berbeza yang diukur apabila parameter fungsi yang berbeza ditetapkan pada kedudukan rata.strategy.closeFungsi ini tidak mempunyai parameter untuk menentukan harga pesanan terendah untuk kedudukan terendah. Fungsi ini digunakan terutamanya untuk kedudukan terendah dengan harga pasaran semasa.
3、strategy.close_all
strategy.close_allFungsi ini digunakan untuk meratakan semua pegangan semasa, kerana skrip bahasa Pine hanya boleh memegang pegangan satu arah, iaitu jika ada isyarat yang berlawanan dengan arah pegangan semasa akan mencetuskan pegangan semasa dan kemudian mencetuskan pegangan berdasarkan isyarat. Oleh itu.strategy.close_allApabila dipanggil, ia akan menghapuskan semua pegangan di arah semasa.strategy.close_allParameter utama fungsi ialah:when。
parameter:
whenSyarat pelaksanaan:
Kami menggunakan contoh untuk melihat:
pine
/*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 pegangan adalah 0...strategy.position_size==0Jadi, apabila ia memenuhi syarat yang ditetapkan oleh parameter when, ia hanya akan melaksanakan ID sebagai set yang panjang.strategy.entryFungsi kemasukan: selepas memegang banyak kedudukanstrategy.position_sizeLebih besar daripada 0, maka ID adalah fungsi masuk short yang mungkin dilaksanakan, kerana kedudukan yang memegang banyak kepala, isyarat pembalikan shorting yang muncul pada masa ini akan menyebabkan kedudukan yang memegang banyak kepala kosong. Kemudian kita menulis dalam keadaan if apabilastrategy.position_size < 0Apabila memegang kedudukan kosong, maka ia akan menebus semua kedudukan yang dipegang pada masa ini.enableStop := true│Menghentikan pelaksanaan strategi untuk melihat log │
boleh didapatistrategy.close_allFungsi ini tidak mempunyai parameter untuk menentukan harga pesanan terendah untuk kedudukan terendah. Fungsi ini digunakan terutamanya untuk kedudukan terendah dengan harga pasaran semasa.
4、strategy.exit
strategy.exitFungsi ini digunakan untuk operasi kedudukan kosong untuk memegang kedudukan masuk, yang berbeza dengan fungsi ini ialahstrategy.closedanstrategy.close_allFungsi ini adalah untuk segera menebus kedudukan pada harga pasaran semasa.strategy.exitFungsi akan melakukan perancangan kedudukan rata mengikut parameter yang ditetapkan.
parameter:
id: ID pesanan untuk borang terhad ini.from_entry: ID kemasukan yang digunakan untuk menentukan operasi setinggi.qty: Bilangan simpanan kosong.qty_percentPeratusan saham kosong, julat: 0 ~ 100 ◦profit: Matlamat keuntungan, dalam mata.loss: Matlamat Hentikan Kerosakan, dalam mata.limit: Matlamat keuntungan, dengan harga yang ditetapkan.stop: Matlamat Hentikan Kerosakan, dengan harga yang ditetapkan.whenSyarat pelaksanaan:
Menggunakan strategi ujian untuk memahami penggunaan parameter.
pine
/*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语言模板参数上「定价货币精度」参数设置有关
Dengan menggunakan ujian balasan model harga masa nyata, strategi ujian ini bermula dengan melakukan 3 operasi kemasukan:strategy.entryFungsi), <unk>long1 <unk> sengaja ditetapkanlimitParameter, harga langganan adalah 1 sehingga ia tidak boleh diperdagangkan. Kemudian uji syarat fungsi keluarstrategy.exit❚ Menggunakan penangguhan mengikut bilangan titik, penangguhan mengikut harga, menggunakan kedudukan jumlah tetap tetap, menggunakan penangguhan mengikut peratusan. ❚ Oleh kerana contoh lebar hanya menunjukkan penangguhan. ❚ Operasi penangguhan juga sama.strategy.exitFungsi ini juga mempunyai parameter tracking stop loss yang lebih kompleks:trail_price、trail_points、trail_offsetAnda juga boleh menguji cara menggunakannya dalam contoh ini.
5、strategy.cancel
strategy.cancelFungsi yang digunakan untuk membatalkan / menghentikan semua arahan untuk senarai pendahuluan.strategy.order, strategy.entry , strategy.exitIa boleh menghasilkan ID kemasukan. Parameter utama fungsi ini adalah:id、when。
parameter:
idID yang perlu dibatalkan:whenSyarat pelaksanaan:
Fungsi ini difahami sebagai fungsi yang digunakan untuk membatalkan perintah kemasukan yang tidak bertransaksi.
pine
/*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 ◦ membatalkan / menghentikan semua arahan senarai pendahuluan ◦ boleh ditetapkanwhenParameter
parameter:
whenSyarat pelaksanaan:
pine
/*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 fungsi, parameter, dan sebagainya hampir sama denganstrategy.entryPersamaan, perbezaanstrategy.orderFungsi tidak dilindungistrategyFungsipyramidingPengaturan parameter memberi kesan, tiada had jumlah pesanan.
parameter:
id: boleh difahami sebagai nama pertama yang diberikan kepada kedudukan perdagangan tertentu untuk rujukan. Boleh merujuk kepada id ini untuk membatalkan, mengubah suai pesanan, dan mendatarkan kedudukan.directionParameter ini akan diteruskan jika arah pesanan adalah melakukan lebih banyak (atau membeli)strategy.longVariabel ini akan dihantar kepada anda jika anda ingin menjual.strategy.shortVariabel ini ialah:qty: Tentukan jumlah pesanan, jika anda tidak menghantar parameter ini, anda akan menggunakan jumlah pesanan lalai.whenKeadaan pelaksanaan: anda boleh menentukan parameter ini untuk mengawal sama ada operasi perintah semasa ini akan dicetuskan.limitTentukan harga yang terhad untuk pesanan.stop: Harga Hentikan Kerosakan.
Kita akan gunakanstrategy.orderTidak ada had untuk jumlah siri, dan ia adalah gabunganstrategy.exitFungsi Terma Exit Fungsi Terma Exit Fungsi. Membina skrip yang menyerupai transaksi grid. Contoh sangat mudah, hanya untuk pembelajaran:
pine
/*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-contoh strategi dalam tutorial ini hanya digunakan untuk strategi pengajaran, strategi bimbingan dan reka bentuk idea, tidak melakukan apa-apa panduan perdagangan, cadangan.
Strategi penunjuk trend super
pine
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()
Strategi trend yang ditulis dalam bahasa Pine sangat mudah, di sini kita merancang strategi trend yang mudah untuk dilacak dengan indikator trend super. Mari kita menganalisis kod sumber strategi ini.
Pertama, gunakan kod strategi.strategyFungsi melakukan beberapa tetapan mudah:strategy("supertrend", overlay=true)Ia hanya menetapkan satu tajuk strategi yang dipanggil "supertrend".overlayParameternya ialahtrueKita merancang strategi Pine atau kita belajar skrip strategi Pine. Pertama kita lihat pada reka bentuk parameter antara muka strategi, kita lihat pada kod sumber untuk strategi indikator trend super, di mana kita telah belajar dalam kursus sebelum ini.inputfungsi
[supertrend, direction] = ta.supertrend(input(5, "factor"), input.int(10, "atrPeriod"))
inputPanggilan fungsi digunakan secara langsung sebagaita.supertrendParameter fungsi penunjuk digunakan untuk mengira penunjuk trend super. Di antaranya:
- input(5, "factor")
- input.int(10, "atrPeriod")
Secara lalai, fungsi akan menetapkan dua kawalan parameter pada antara muka dasar bahasa Pine, seperti yang ditunjukkan di bawah:
Seperti yang anda lihat, nilai lalai pada alat kawalan adalahinputFungsi daninputFungsi siri ialahinput.intFungsi ini juga boleh digunakan untuk menetapkan antara muka strategi (seperti yang telah dijelaskan di dalam bab sebelumnya).ta.supertrendFungsi ini mempunyai parameter: Fungsi Super Trend Indicator yang dikira sebagai data harga.supertrenddan satu data arahdirection◦ Kemudian gunakanplotMenggambar grafik fungsi, perhatikan bahawa ketika menggambar grafik berdasarkan arah indikator trend super, hanya menggambar arah semasa. ApabiladirectionUntuk -1 masa trend semasa adalah ke atas, apabiladirectionJadi, kita boleh lihat bahawa dalam satu jam, trend semasa adalah menurun.plotFungsi yang difikirkan semasa melukisdirectionLebih besar daripada, kurang daripada 0.
Seterusnyaif ... else ifLogik adalah penghakiman isyarat perdagangan, apabila ungkapandirection < 0Untuk menggambarkan keadaan semasa dalam masa nyata, apabila data harga dalam indikator super trendsupertrendLebih tinggi daripada harga petanda trend super pada 2 BAR ke hadapan (iaitusupertrend[2],还记得历史操作符引用某个变量历史数据吧Jika anda mempunyai kedudukan semasa, anda boleh memanggil fungsi pesanan terbalik untuk menebus kedudukan sebelumnya dan membuka kedudukan mengikut arah perdagangan semasa.supertrend > supertrend[2]Syarat tidak tercapai, asalkan pada masa inistrategy.position_size < 0Ia juga boleh mencetuskan kemerosotan dalam pasaran saham.strategy.close_all()Pelaksanaan fungsi, untuk melakukan semua kedudukan kosong.
direction > 0Begitu juga ketika berada dalam tahap trend menurun, jika terdapat lebih banyak pemegang, semua pemegang akan dipadamkan, dan kemudian memenuhi syaratsupertrend < supertrend[3]Ini adalah satu-satunya cara yang anda boleh menggunakan untuk mematikan telefon anda apabila anda memicu isyarat kosong.[3]Mungkin ini adalah niat ahli strategi, kerana dalam beberapa pasaran seperti pasaran perdagangan kontrak, risiko shorting sedikit lebih besar daripada risiko over.
untukta.supertrend"Apakah ada pelajar yang berminat untuk mengetahui bagaimana ia boleh menentukan sama ada trend semasa adalah naik atau turun?"
Malah, indikator ini juga boleh diwujudkan dalam bentuk fungsi tersuai dalam bahasa Pine:
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 fungsi tersuai dan fungsi terbina dalamta.supertrendAlgoritma yang sama, dan tentu saja data penunjuk yang dikira sama.
Dari algoritma fungsi tersuai ini, kita dapat melihat bahawa Pine built-in Super Trend Indicator menggunakanhl2Variabel terbina dalam ((harga tertinggi, harga terendah ditambah dan kemudian dibahagikan dengan 2, iaitu nilai purata harga tertinggi dan harga terendah), dan kemudian mengira indikator ATR untuk tempoh tertentu berdasarkan parameteratrPeriod ((gelombang) ⋅ dan kemudian menggunakan hl2 dan ATR untuk membina atas, bawah. ⋅
Kemas kini berdasarkan ekspresi trigonometri dalam kodlowerBanddanupperBand。
pine
lowerBand := lowerBand > prevLowerBand or close[1] < prevLowerBand ? lowerBand : prevLowerBand
upperBand := upperBand < prevUpperBand or close[1] > prevUpperBand ? upperBand : prevUpperBand
lowerBand: garisan bawah, digunakan untuk menentukan sama ada trend naik berubah. upperBand: garisan atas, digunakan untuk menentukan sama ada trend turun berubah. lowerBand dan upperBand sentiasa dikira, hanya pada fungsi tersuai ini yang akhirnya menentukan arah trend semasa.
pine
else if prevSuperTrend == prevUpperBand
direction := close > upperBand ? -1 : 1
else
direction := close < lowerBand ? 1 : -1
Ini adalah satu-satunya cara untuk menilai jika bar yang terdahulu adalah satu-satu bar.prevUpperBand, iaitu garisan atas, menunjukkan trend ke bawah.closemelebihiupperBandHarga pecah, dan pada masa ini trend berubah, dan beralih ke arah kenaikan.directionJadi, jika anda melihat dalam strategi supertrend, anda akan melihat dalam strategi supertrend, jika anda melihat dalam strategi supertrend, anda akan melihat dalam strategi supertrend.if direction < 0Apabila keadaan isyarat memicu, lakukan lebih banyak lagi.direction > 0Apabila, keadaan isyarat mencetuskan kosong.
pine
superTrend := direction == -1 ? lowerBand : upperBand
[superTrend, direction]
Akhirnya, data harga dan data arah yang dipilih oleh arah akan dikembalikan kepada indikator supertrend tertentu.
Strategi Keseimbangan Dinamis
pine
/*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)
Kita teruskan dengan beberapa contoh reka bentuk strategi bahasa Pine, kali ini kita akan melihat strategi keseimbangan dinamik.BaseCurrencyJumlah (jenis dagangan) danQuoteCurrencyJumlah (mata wang) sentiasa melakukan rawatan keseimbangan. Aset mana yang meningkat harga relatif, nilai yang dipegang dalam akaun meningkat, aset mana yang dijual. Jika harga relatif aset menurun, nilai yang dipegang dalam akaun berkurang, membeli aset tersebut. Ini adalah apa yang disebut strategi keseimbangan dinamik. Strategi keseimbangan dinamik yang praktikal akan menjadi strategi grid, yang berfungsi dengan baik dalam keadaan gegaran. Tetapi dalam keadaan trend, kerugian akan berterusan, perlu menunggu harga kembali untuk mengurangkan kerugian secara perlahan-lahan sehingga menghasilkan keuntungan, tetapi lebih baik dalam strategi keseimbangan dinamik akhirnya dapat menangkap pergerakan gegaran dalam keadaan pergerakan.
Kelemahan seperti yang ditunjukkan pada carta pengukuran strategi ini, pada tahap kenaikan harga yang besar (atau penurunan besar), strategi ini mempunyai kerugian yang lebih besar. Oleh itu, strategi ini baik untuk strategi tunai, dan penggunaan berjangka memerlukan kawalan risiko yang baik.
Mari kita lihat rancangan kod strategi:
Kami menggunakan reka bentuk yang mudah untuk mensimulasikan strategibalance(iaitu jumlah aset QuotCurrency) danstocks(iaitu jumlah aset BaseCurrency) maklumat keseimbangan. Kita tidak membaca jumlah aset sebenar dalam akaun, kita hanya menggunakan jumlah simulasi untuk mengira pembelian dan penjualan yang sesuai.maxDiffValue, parameter ini adalah standard penilaian untuk keseimbangan. Pada harga semasa, hanya apabilaBaseCurrencydanQuoteCurrencyKecacatan melebihimaxDiffValueIni adalah masa untuk menyeimbangkan, menjual aset yang mahal, membeli aset yang murah, dan menyeimbangkan semula aset.
Timbulnya isyarat perdagangan strategi mestilah bermakna pada tahap BAR masa nyata, jadi syarat perdagangan strategi ditetapkan dalam penilaian ifnot barstate.ishistory◦ Bergantung kepada harga semasa, ia adalah kira-kira RM5 juta.balanceNilai melebihistocksBeli semasa nilai. Sebaliknya, lakukan operasi jual. Kemas kini selepas melaksanakan pernyataan transaksibalancedanstocksVariable, kemudian menunggu untuk trigger keseimbangan seterusnya.
Maklumat di atas adalah harga varieti pada masa permulaan pengesanan, harga 1458, jadi saya sengaja menetapkan parameterbalanceJadi: 47741458*3) Tetapkan parameterstocksUntuk: 3. Pastikan aset berada dalam keadaan seimbang pada permulaan.
Strategi Supertrend untuk Mengesan dan Menghentikan Kerosakan
Dalam pelajaran sebelumnya, kita telah belajar bahawastrategy.exitFungsi penyingkiran kedudukan, di mana fungsi penghentian dan penghentian kehilangan kami tidak mempunyai contoh.strategy.exitFungsi Tracking Stop Loss Stop untuk mengoptimumkan strategi Super Trend.
Pertama, mari kita lihatstrategy.exitParameter trace stop loss untuk fungsi:
1、trail_priceParameter: Triggered Placing Tracking Stop Stop Loss Placements Logical Actions Position ((di tempat yang ditentukan oleh harga) <unk>
2、trail_offsetParameter: jarak antara satuan kedudukan kosong yang diletakkan dengan harga tertinggi ((bila melakukan banyak) atau harga terendah ((bila melakukan kosong) selepas melakukan tindakan berhenti berhenti.
3、trail_pointsParameter: samatrail_priceParameter, hanya ditetapkan sebagai kedudukan dengan bilangan kelebihan <unk>.
Tidak mengapa jika ia sukar untuk difahami! Mari kita fahami pembelajaran melalui satu strategi untuk mengkaji semula situasi, ia sebenarnya sangat mudah.
pine
/*backtest
start: 2022-09-23 00:00:00
end: 2022-09-23 08:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["RunMode",1,358374],["ZPrecision",0,358374]]
*/
strategy("test", overlay = true)
varip a = na
varip highPrice = na
varip isTrade = false
varip offset = 30
if not barstate.ishistory and not isTrade
strategy.entry("test 1", strategy.long, 1)
strategy.exit("exit 1", "test 1", 1, trail_price=close+offset, trail_offset=offset)
a := close + offset
runtime.log("每点价格为:", syminfo.mintick, ",当前close:", close)
isTrade := true
if close > a and not barstate.ishistory
highPrice := na(highPrice) ? close : highPrice
highPrice := close > highPrice ? close : highPrice
plot(a, "trail_price 触发线")
plot(strategy.position_size>0 ? highPrice : na, "当前最高价")
plot(strategy.position_size>0 ? highPrice-syminfo.mintick*offset : na, "移动止损触发线")
Strategi ini bermula dengan pelaksanaan multicasting serta-merta, dan kemudian seterusnya.strategy.exitPerintah keluar ((menentukan parameter tracking stop loss), apabila kenaikan harga bergerak melebihi garis pemicu trail_price, mula melaksanakan logik tracking stop loss, garis stop loss ((biru) mula mengikuti perubahan harga tertinggi, kedudukan garis biru adalah harga yang menyebabkan stop loss memicu kedudukan rata, dan akhirnya apabila harga bergerak jatuh di bawah garis biru, maka ia memicu kedudukan rata. Dengan cara ini, garis yang digambar pada carta tidak mudah difahami.
Jadi, kita gunakan fungsi ini untuk mengoptimumkan strategi super trend dengan hanya menetapkan satu pesanan masuk kepada strategi.strategy.exitIa boleh ditambah pada jadual perjalanan anda untuk mengesan dan menghentikan kerosakan.
pine
if not barstate.ishistory and findOrderIdx("open") >= 0 and state == 1
trail_price := strategy.position_size > 0 ? close + offset : close - offset
strategy.exit("exit", "open", 1, trail_price=trail_price, trail_offset=offset)
runtime.log("每点价格为:", syminfo.mintick, ",当前close:", close, ",trail_price:", trail_price)
state := 2
tradeBarIndex := bar_index
Kod strategi lengkap:
pine
/*backtest
start: 2022-05-01 00:00:00
end: 2022-09-27 00:00:00
period: 1d
basePeriod: 5m
exchanges: [{"eid":"Binance","currency":"ETH_USDT"}]
args: [["RunMode",1,358374],["ZPrecision",0,358374]]
*/
varip trail_price = na
varip offset = input(50, "offset")
varip tradeBarIndex = 0
// 0 : idle , 1 current_open , 2 current_close
varip state = 0
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
if strategy.position_size == 0
trail_price := na
state := 0
[superTrendPrice, dir] = ta.supertrend(input(2, "atr系数"), input(20, "atr周期"))
if ((dir[1] < 0 and dir[2] > 0) or (superTrendPrice[1] > superTrendPrice[2])) and state == 0 and tradeBarIndex != bar_index
strategy.entry("open", strategy.long, 1)
state := 1
else if ((dir[1] > 0 and dir[2] < 0) or (superTrendPrice[1] < superTrendPrice[2])) and state == 0 and tradeBarIndex != bar_index
strategy.entry("open", strategy.short, 1)
state := 1
// 反向信号,全平
if strategy.position_size > 0 and dir[2] < 0 and dir[1] > 0
strategy.cancel_all()
strategy.close_all()
runtime.log("趋势反转,多头全平")
else if strategy.position_size < 0 and dir[2] > 0 and dir[1] < 0
strategy.cancel_all()
strategy.close_all()
runtime.log("趋势反转,空头全平")
if not barstate.ishistory and findOrderIdx("open") >= 0 and state == 1
trail_price := strategy.position_size > 0 ? close + offset : close - offset
strategy.exit("exit", "open", 1, trail_price=trail_price, trail_offset=offset)
runtime.log("每点价格为:", syminfo.mintick, ",当前close:", close, ",trail_price:", trail_price)
state := 2
tradeBarIndex := bar_index
plot(superTrendPrice, "superTrendPrice", color=dir>0 ? color.red : color.green, overlay=true)
- 1




















