Tutorial pengenalan Bahasa PINE FMZ Quant

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

[TOC]

img

Tutorial pengenalan Bahasa PINE FMZ Quant

Sokongan tutorial video:https://www.youtube.com/watch?v=CA3SwJQb_1g

FMZ Quant Trading Platform menyokong penulisan strategi bahasa Pine, backtesting, dan perdagangan langsung strategi bahasa Pine, dan ia serasi dengan versi bahasa Pine yang lebih rendah.Strategy Squaredi Platform Perdagangan Kuantum FMZ (FMZ.COM).

FMZ menyokong bukan sahaja bahasa Pine, tetapi juga fungsi lukisan bahasa Pine yang kuat. Pelbagai fungsi, alat yang kaya dan praktikal, pengurusan yang cekap dan mudah di platform FMZ lebih meningkatkan kelayakan strategi (skrip) Pine. Berdasarkan keserasian dengan bahasa Pine, FMZ juga memperluaskan, mengoptimumkan dan memotong bahasa Pine ke tahap tertentu. Sebelum memasuki tutorial secara rasmi, mari kita lihat apa perubahan yang telah dibuat pada bahasa Pine di FMZ berbanding versi asal.

Gambaran ringkas mengenai beberapa perbezaan yang jelas:

    1. Strategi Pine pada FMZ, pengenal versi pada permulaan kod//@versiondanstrategy, indicatorpernyataan di awal kod tidak wajib untuk menulis, FMZ tidak menyokongimportuntuk diimportlibraryberfungsi buat masa ini.

    Ia boleh dilihat bahawa beberapa strategi yang ditulis seperti ini:

    //@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 tulis seperti ini:

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

    Pada FMZ ia boleh disederhanakan kepada:

    src = 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:

    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)
    
    1. Sesetengah tetapan strategi yang berkaitan dengan perdagangan (script) ditetapkan oleh Pine Language Trading Class Library parameter pada antara muka strategi FMZ.
    • Model harga penutupan dan model harga masa nyata Pada pandangan perdagangan, kita boleh menggunakancalc_on_every_tickparameterstrategyfungsi untuk menetapkan skrip strategi untuk melaksanakan logik strategi dalam masa nyata apabila harga berubah setiap kali.calc_on_every_tickparameter harus ditetapkan kepadatrue.calc_on_every_tickParameter lalai ialahfalse, iaitu, logik strategi dilaksanakan hanya apabila BAR garis K semasa strategi telah selesai sepenuhnya. Pada FMZ, ia ditetapkan oleh parameter Pine Language Trading Class Library templat.

      img

    • Kawalan ketepatan berangka, seperti harga dan jumlah pesanan apabila strategi dilaksanakan perlu ditentukan pada FMZ Pada pandangan perdagangan, tidak ada masalah ketepatan apabila meletakkan pesanan dagangan sebenar, kerana ia hanya boleh diuji dalam simulasi. Pada FMZ, adalah mungkin untuk menjalankan strategi Pine dalam perdagangan sebenar. Kemudian strategi perlu dapat menentukan ketepatan harga dan ketepatan jumlah pesanan dari pelbagai dagangan dengan fleksibel. Tetapan ketepatan mengawal bilangan tempat perpuluhan dalam data yang berkaitan untuk mencegah data tidak memenuhi keperluan pesanan bursa dan dengan itu gagal untuk meletakkan pesanan.

    • Kod kontrak niaga hadapan Jika produk dagangan di FMZ adalah kontrak, ia mempunyai dua atribut, masing-masing Trading Pair dan Contract Code. Selain menetapkan pasangan dagangan secara eksplisit, juga perlu menetapkan kod kontrak tertentu dalam parameter Variety Code templat Pine Language Trading Class Library semasa perdagangan sebenar dan backtesting. Sebagai contoh, untuk kontrak kekal, isi dalamswap, dan kod kontrak bergantung kepada sama ada bursa yang beroperasi mempunyai kontrak tersebut.quarterKod kontrak ini adalah konsisten dengan kod kontrak niaga hadapan yang ditakrifkan dalam dokumen API bahasa Javascript / python / c ++ FMZ.

    Untuk tetapan lain, seperti jumlah pesanan minimum, jumlah pesanan lalai, dan lain-lain, sila rujuk pengenalan parameter padaTemplat argumen perpustakaan kelas perdagangan bahasa paindalam dokumentasi bahasa Pine.

    1. Fungsi untuk sambungan FMZ:runtime.debug , runtime.log, runtime.errordigunakan untuk debugging.

    3 fungsi telah ditambahkan ke platform FMZ untuk debug.

    • runtime.debug: Mencetak maklumat pembolehubah pada konsol, yang biasanya tidak digunakan dengan fungsi ini.

    • runtime.log: output dalam log. fungsi khusus bahasa PINE di FMZ.

      runtime.log(1, 2, 3, close, high, ...), Multiple parameters can be passed.
      
    • runtime.error: Ia akan menyebabkan ralat semasa berjalan dengan mesej ralat yang ditentukan dalam parameter mesej apabila dipanggil.

      runtime.error(message)
      
    1. Peraturanoverlayparameter dilanjutkan dalam beberapa fungsi lukisan

    Dalam bahasa Pine di FMZ, fungsi lukisanplot, plotshape, plotchar, dll telah menambahoverlaysokongan parameter, yang membolehkan untuk menentukan lukisan pada carta utama atau sub-grafik.overlayditetapkan kepadatrueuntuk menarik pada carta utama, danfalseditetapkan untuk menarik pada sub-grafik, yang membolehkan strategi Pine di FMZ untuk menarik carta utama dan sub-grafik pada masa yang sama.

    1. Nilai daripadasyminfo.mintickpembolehubah terbina dalam

    Peralihan terbina dalamsyminfo.mintickditentukan sebagai nilai tick minimum untuk simbol semasa. Nilai ini boleh dikawal oleh parameter templat harga currency precision dalam Pine Language Trading Class Library pada FMZbot/Ujian belakangPricing currency accuracy setting 2 bermaksud bahawa harga adalah tepat kepada tempat perpuluhan kedua semasa perdagangan, dan unit perubahan harga minimum adalah 0.01.syminfo.mintickadalah 0.01.

    1. Harga purata di FMZ PINE Script semua termasuk komisen

    Sebagai contoh: harga pesanan adalah 8000, arah penjualan, kuantiti adalah 1 lot (sepotong, lembaran), harga purata selepas transaksi bukan 8000, tetapi lebih rendah daripada 8000 (kos termasuk yuran pengendalian).

Asas Bahasa Pine

Apabila mula mempelajari asas-asas bahasa Pine, mungkin ada beberapa contoh arahan dan tatabahasa kod yang kita tidak biasa. Tidak kira jika anda tidak faham, kita boleh membiasakan diri dengan konsep terlebih dahulu dan memahami tujuan ujian, atau anda boleh memeriksa dokumentasi bahasa Pine di FMZ untuk arahan. Kemudian ikuti tutorial langkah demi langkah untuk membiasakan diri dengan pelbagai tatabahasa, arahan, fungsi, dan pembolehubah terbina dalam.

Pelaksanaan model

Apabila mula belajar bahasa Pine, sangat perlu untuk memahami konsep yang berkaitan seperti proses pelaksanaan program skrip bahasa Pine. Strategi bahasa Pine berjalan berdasarkan carta. Kita dapat memahami bahawa strategi bahasa Pine adalah satu siri pengiraan dan operasi, yang dijalankan pada carta mengikut urutan siri masa dari data tertua yang telah dimuat naik pada carta. Jumlah data yang dimuat naik carta pada mulanya adalah terhad. Dalam perdagangan sebenar, jumlah maksimum data biasanya ditentukan berdasarkan jumlah data maksimum yang dikembalikan oleh antara muka pertukaran, dan jumlah maksimum data semasa backtesting ditentukan berdasarkan data yang disediakan oleh sumber data sistem backtesting. Bar K-line paling kiri pada carta, iaitu set data pertama carta, mempunyai nilai indeks 0.bar_indexdalam bahasa Pine.

plot(bar_index, "bar_index")

img

Peraturanplotfungsi adalah salah satu fungsi yang kita akan menggunakan lebih banyak pada masa akan datang. penggunaan adalah sangat mudah, ia adalah untuk menarik garis pada carta mengikut parameter input, data input adalahbar_index, dan garisan itu dinamakan sebagaibar_index. Ia dapat dilihat bahawa nilai baris bernama bar_index pada Bar pertama adalah 0, dan ia meningkat dengan 1 ke kanan apabila Bar meningkat.

Kerana tetapan strategi berbeza, kaedah pelaksanaan model strategi berbeza, mereka boleh dibahagikan kepada:closing price modeldanreal-time price modelKami juga telah memperkenalkan konsep mereka secara ringkas sebelum ini.

  • Model harga penutupan

    Apabila kod strategi dilaksanakan, tempoh Bar K-garis semasa dilaksanakan sepenuhnya, dan apabila Bar K-garis ditutup, tempoh K-garis telah selesai. Pada ketika ini, logik strategi Pine dilaksanakan sekali, dan isyarat perdagangan yang dicetuskan akan dilaksanakan pada permulaan Bar K-garis seterusnya.

  • Model harga masa nyata

    Apabila kod strategi dilaksanakan, tanpa mengira sama ada Bar K-line semasa ditutup atau tidak, logik strategi Pine akan dilaksanakan apabila pasaran berubah setiap kali, dan isyarat perdagangan yang dicetuskan akan dilaksanakan dengan segera.

Apabila strategi bahasa Pine dilaksanakan dari kiri ke kanan pada carta, Bar K-garis pada carta dibahagikan kepadaHistorical BarsdanReal-time Bars:

  • Bar Bersejarah

    Apabila strategi ditetapkan kepada Tick Model dan mula melaksanakan, semua Bar K-garis pada carta kecuali yang paling kanan adalahHistorical Bars. Logik strategi dijalankan hanya sekali pada setiaphistorical bar. Apabila strategi ditetapkan kepada Bar Model dan mula melaksanakan, semua bar pada carta adalahhistorical bars. Logik strategi dijalankan hanya sekali pada setiaphistorical bar.

    Pengiraan berdasarkan Bars sejarah: Kod strategi dilaksanakan sekali dalam keadaan penutupan bar sejarah, dan kemudian kod strategi terus dilaksanakan di bar sejarah seterusnya sehingga semua bar sejarah dilaksanakan sekali.

  • Bar masa nyata

    Apabila strategi dilaksanakan ke Bar K-line terakhir di sebelah kanan, Bar adalah Bar masa nyata. Selepas bar masa nyata ditutup, bar menjadi bar masa nyata yang dilalui (menjadi bar sejarah). Bar masa nyata baru akan dihasilkan di sebelah kanan carta.

    Apabila strategi ditetapkan kepada Tick Model dan mula dilaksanakan, logik strategi akan dilaksanakan sekali untuk setiap perubahan pasaran pada bar masa nyata. Apabila strategi ditetapkan kepada Bar Model dan mula dilaksanakan, bar masa nyata tidak akan dipaparkan pada carta.

    Pengiraan berdasarkan Bar masa nyata: Jika strategi ditetapkan kepada Bar Model dan carta tidak memaparkan bar masa nyata, kod strategi hanya akan dilaksanakan sekali apabila bar semasa ditutup. Jika strategi ditetapkan kepada Tick Model, pengiraan pada bar masa nyata adalah sama sekali berbeza dari bar sejarah, dan kod strategi akan dilaksanakan sekali untuk setiap perubahan pasaran pada bar perdagangan langsung.high, low, closeadalah ditentukan pada Bar sejarah, dan nilai-nilai ini boleh berubah setiap kali pasaran berubah pada Bar masa nyata. oleh itu, data seperti penunjuk yang dikira berdasarkan nilai-nilai ini juga akan berubah dalam masa nyata. pada Bar masa nyata,closesentiasa mewakili harga terkini semasa, danhighdanlowsentiasa mewakili titik tertinggi dan titik terendah yang dicapai sejak permulaan bar masa nyata semasa. pembolehubah terbina dalam ini mewakili nilai akhir Bar masa nyata apabila ia terakhir dikemas kini.

    Mekanisme rollback apabila melaksanakan strategi pada Bar masa nyata (model harga masa nyata): Semasa pelaksanaan Bar masa nyata, menetapkan semula pembolehubah yang ditakrifkan pengguna sebelum setiap iterasi baru strategi dipanggil rollback. Mari kita memahami mekanisme rollback dengan contoh kod ujian berikut.

    Perhatian:

    /*backtest 
    ...
    ..
    .
    */
    

    Kandungan pakej adalah maklumat konfigurasi backtest yang disimpan dalam bentuk kod pada platform FMZ.

    /*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("before n + 1, n:", n, " current bar_index:", bar_index)
        n := n + 1
        runtime.log("after n + 1, n:", n, " current bar_index:", bar_index)
      
    plot(n, title="n")
    

    img

Kami hanya memeriksa adegan yang dilaksanakan semasa masa nyata Bars, jadi kami menggunakannot barstate.ishistoryungkapan untuk mengehadkan pengumpulan pembolehubah n hanya dalam Bar masa nyata, dan penggunaanruntime.logfungsi untuk mengeluarkan maklumat dalam log strategi sebelum dan selepas operasi pengumpulan.plot, dapat dilihat bahawa n sentiasa 0 apabila strategi dijalankan dalam Bars bersejarah. Apabila Bar masa nyata dilaksanakan, operasi penambahan 1 ke n dicetuskan, dan operasi penambahan 1 ke n dilaksanakan apabila strategi dilaksanakan dalam setiap pusingan Bar masa nyata. Ia dapat diperhatikan dari mesej log bahawa n akan disetel semula ke nilai yang akhirnya dikemukakan oleh strategi pelaksanaan Bar sebelumnya apabila kod strategi dijalankan semula dalam setiap pusingan. Kemas kini nilai n akan dikemukakan apabila kod strategi dijalankan pada Bar masa nyata untuk kali terakhir, jadi anda dapat melihat bahawa nilai kurva n meningkat sebanyak 1 dengan setiap peningkatan Bar bermula dari Bar masa nyata pada carta.

Ringkasan:

  1. Kod strategi dilaksanakan sekali setiap kali pasaran dikemas kini apabila strategi mula dilaksanakan dalam Bar masa nyata.
  2. Apabila dijalankan dalam Bar masa nyata, pembolehubah digulung kembali setiap kali sebelum kod strategi dijalankan.
  3. Apabila dijalankan dalam Bar masa nyata, pembolehubah dihantar sekali apabila penutupan dikemas kini.

Oleh kerana data rollback, operasi lukisan, seperti lengkung pada carta juga boleh menyebabkan menggambar semula.

var n = 0
if not barstate.ishistory
    runtime.log("before n + 1, n:", n, " current bar_index:", bar_index)
    n := open > close ? n + 1 : n
    runtime.log("after n + 1, n:", n, " current bar_index:", bar_index)
  
plot(n, title="n")

Tangkapan skrin masa Aimg

Tangkapan skrin masa Bimg

Kami hanya mengubahsuai ayat:n := open > close ? n + 1 : n, hanya menambah 1 kepada n apabila Bar masa nyata semasa adalah garis negatif (iaitu, harga pembukaan lebih tinggi daripada harga penutupan). Ia dapat dilihat bahawa dalam carta pertama (waktu A), kerana harga pembukaan lebih tinggi daripada harga penutupan (garis negatif) pada masa itu, n dikumpulkan oleh 1, dan nilai n yang dipaparkan pada kurva carta adalah 5. Kemudian pasaran berubah dan harga dikemas kini seperti yang ditunjukkan dalam carta kedua (waktu B). Pada masa ini, harga pembukaan lebih rendah daripada harga penutupan (garis positif), dan nilai n bergolak kembali tanpa meningkat 1. kurva n dalam carta juga digambar semula dengan segera, dan nilai n pada kurva adalah 4. Oleh itu, isyarat, seperti crossup dan dipaparkan pada bar masa nyata, tidak pasti dan boleh berubah.

  • Konteks pembolehubah dalam fungsi

    Mari kita belajar pembolehubah dalam fungsi bahasa Pine bersama-sama. Menurut beberapa penerangan pada tutorial Pine, pembolehubah dalam fungsi mempunyai perbezaan berikut dari pembolehubah di luar fungsi:

    Sejarah pembolehubah siri yang digunakan dalam fungsi Pine dibuat dengan setiap panggilan berturut-turut kepada fungsi. Jika fungsi tidak dipanggil pada setiap bar di mana skrip dijalankan, ini akan mengakibatkan perbezaan antara nilai sejarah siri di dalam dan di luar blok tempatan fungsi. Oleh itu, jika fungsi tidak dipanggil pada setiap bar, siri yang dirujuk di dalam dan di luar fungsi dengan nilai indeks yang sama tidak akan merujuk kepada titik sejarah yang sama.

    Jangan risau, kita akan mencari tahu dengan kod ujian yang berjalan di FMZ:

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

    Tangkapan skrin menjalankan backtest

    img

    Kod ujian agak mudah, terutamanya untuk memeriksa data yang dirujuk oleh dua kaedah, iaitu:f(a) => a[1]danf2() => close[1].

    • f(a) => a[1]: Menggunakan kaedah lulus parameter, fungsi kembali kea[1] finally.

    • f2() => close[1]: Gunakan pembolehubah terbina dalamclosesecara langsung, dan fungsi kembali keclose[1] finally.

Peraturan[]simbol digunakan untuk merujuk kepada nilai sejarah pembolehubah siri data, dan menutup[1] 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")Menggambar watak A, warna adalah merah, ia digambar apabila oneBarInTwo adalah benar, dan kedudukan yang digambar (pada paksi Y adalah: nilai yang dikembalikan olehf(close).

  • plotchar(oneBarInTwo ? f2() : na, title = "f2()", color = color.green, location = location.absolute, style = shape.circle, overlay = true, char = "B")Menggambar watak B, warna adalah hijau, ia digambar hanya apabila oneBarInTwo adalah benar, dan kedudukan yang digambar (pada paksi Y adalah: nilai yang dikembalikan olehf2().

  • plot(close[2], title = "close[2]", color = color.red, overlay = true)Gambar garis, warna adalah merah, dan kedudukan yang digambar (pada paksi Y) adalah:close[2], yang merupakan harga penutupan bar kedua sebelum bar semasa (mengira 2 bar ke kiri).

  • plot(close[1], title = "close[1]", color = color.green, overlay = true)Gambar garis, warna hijau, dan kedudukan yang digambar (pada paksi Y) adalah:close[1], yang merupakan harga penutupan bar pertama sebelum bar semasa (mengira 1 bar ke kiri).

Ia boleh dilihat dari tangkapan skrin strategi backtesting bahawa walaupun kedua-dua fungsif(a) => a[1]digunakan untuk menarik penanda A dan fungsif2() => close[1]digunakan untuk menarik penanda B menggunakan [1] untuk merujuk kepada data sejarah pada siri data, kedudukan penanda A dan B pada carta adalah sama sekali berbeza.plot(close[2], title = "close[2]", color = color.red, overlay = true), data yang digunakan untuk melukis garis adalahclose[2].

img

Sebabnya adalah untuk mengira sama ada untuk menarik penanda A dan B melalui indeks Bar K-garis, iaitu pembolehubah terbina dalambar_index. Penanda A dan B tidak digambar pada setiap Bar garis K (pengiraan fungsi dipanggil semasa menggambar). Nilai yang dirujuk oleh fungsif(a) => a[1]tidak akan sama dengan nilai yang dirujuk oleh fungsif2() => close[1]jika fungsi tidak dipanggil pada setiap Bar (walaupun kedua-duanya menggunakan indeks yang sama seperti [1]).

  • Sesetengah fungsi terbina dalam perlu dikira pada setiap Bar untuk mengira hasil mereka dengan betul

    Untuk menggambarkan keadaan ini dengan contoh yang mudah:

    res = close > close[1] ? ta.barssince(close < close[1]) : -1
    plot(res, style = plot.style_histogram, color=res >= 0 ? color.red : color.blue)
    

    Kita tulis kod panggilan fungsita.barssince(close < close[1])dalam pengendali ternarcondition ? value1 : value2. Ini menyebabkan fungsi ta.barssince dipanggil hanya apabilaclose > close[1]Tetapi...ta.barssincefungsi adalah untuk mengira bilangan K-garis sejak kali terakhirclose < close[1]Apabila fungsi ta.barssince dipanggil, ia sentiasa dekat > dekat[1], iaitu, harga penutupan semasa lebih besar daripada harga penutupan Bar sebelumnya. Apabila fungsi ta.barssince dipanggil, keadaan dekat < dekat [1] tidak ditubuhkan, dan tidak ada kedudukan baru-baru ini di mana ia memegang.

    ta.barssince: Apabila dipanggil, fungsi mengembalikan na jika syarat tidak pernah dipenuhi sebelum K-line semasa.

Seperti yang ditunjukkan dalam carta:

img

Jadi apabila carta digambar, hanya data dengan nilai untuk pembolehubah res (-1) digambar.

Untuk mengelakkan masalah ini, kita hanya mengambilta.barssince(close < close[1])fungsi panggilan keluar dari pengendali ternar dan menulisnya di luar mana-mana cawangan bersyarat yang mungkin, membuat ia menjalankan pengiraan pada setiap K-garis Bar.

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)

Siri masa

Konsep siri masa sangat penting dalam bahasa Pine, dan ia adalah konsep yang mesti kita fahami apabila kita belajar bahasa Pine. Siri masa bukan jenis tetapi struktur asas untuk menyimpan nilai berterusan pembolehubah dari masa ke masa. Kita tahu bahawa skrip Pine berdasarkan carta, dan kandungan yang paling asas yang dipaparkan dalam carta adalah carta K-line. Siri masa di mana setiap nilai dikaitkan dengan cap masa Bar K-line.openadalah pembolehubah terbina dalam (terbina dalam) bahasa Pine, dan strukturnya adalah untuk menyimpan siri masa harga pembukaan setiap Bar K-garis.openmewakili harga pembukaan semua Bar K-garis dari Bar pertama di awal carta K-garis semasa ke Bar di mana skrip semasa dijalankan.opendalam kod strategi Pine, ia adalah harga pembukaan Bar K-garis apabila kod strategi dijalankan pada masa ini.[]Apabila strategi Pine dilaksanakan pada bar K-garis tertentu, gunakanopen[1]untuk merujuk kepada harga pembukaan Bar K-line sebelumnya (iaitu harga pembukaan tempoh K-line sebelumnya) yang merujuk kepadaopensiri masa di mana bar K-garis ini sedang dijalankan oleh skrip.

  • Peubah pada siri masa sangat mudah untuk pengkomputeran Mari kita ambil fungsi terbina dalamta.cumsebagai contoh:

    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.sum
    

    Kod ujian:

    v1 = 1
    v2 = ta.cum(v1)
    plot(v1, title="v1")
    plot(v2, title="v2")
    plot(bar_index+1, title="bar_index")
    

    Terdapat banyak fungsi terbina dalam sepertita.cumyang boleh memproses data pada siri masa secara langsung. Sebagai contoh,ta.cumadalah pengumpulan nilai yang sepadan dengan pembolehubah yang dihantar pada setiap Bar K-line, dan seterusnya kita menggunakan carta untuk memudahkan pemahaman.

    Proses operasi strategi Berubah terbina dalam bar_index v1 v2
    Strategi berjalan pada bar K-garis pertama 0 1 1
    Strategi ini berjalan pada bar K-garis kedua 1 1 2
    Strategi berjalan pada bar K-garis ketiga 2 1 3
    Strategi berjalan pada N + 1th K-garis Bar N 1 N+1

    Ia dapat dilihat bahawa v1, v2 dan bahkan bar_index adalah semua struktur siri masa, dan terdapat data yang sepadan pada setiap bar. Sama ada kod ujian menggunakan model Bar atau model Tick, satu-satunya perbezaan adalah sama ada Bar masa nyata dipaparkan pada carta. Untuk backtest cepat, kita menggunakan model Tick untuk menguji.

    img

    Kerana pembolehubah v1 adalah 1 pada setiap Bar, apabilata.cum(v1)Fungsi ini dijalankan pada Bar K-garis pertama, hanya ada Bar pertama, jadi hasil pengiraan adalah 1 dan diberikan kepada pembolehubah v2. Bilakahta.cum(v1)adalah dijalankan pada bar K-garis kedua, terdapat 2 bar K-garis (bar_index pembolehubah terbina dalam yang sepadan dengan yang pertama adalah 0, dan yang kedua yang sepadan dengan bar_index pembolehubah terbina dalam adalah 1), jadi hasil pengiraan adalah 2, yang diberikan kepada pembolehubah v2, dan sebagainya.bar_indexadalah meningkat daripada 0, makabar_index + 1Pada carta, kita juga boleh melihat bahawa garis-garisv2danbar_indexbenar-benar bertindih.

    img

    Begitu juga, saya juga boleh menggunakanta.cumfungsi terbina dalam untuk mengira jumlah harga penutupan untuk semua Bar pada carta semasa. semua yang saya perlu lakukan adalah menulis seperti ini:ta.cum(close), Apabila strategi berjalan ke Bar masa nyata di sebelah kanan, hasil yang dikira olehta.cum(close)adalah jumlah harga penutupan semua Bar pada carta (jika tidak berjalan ke sebelah kanan, ia hanya terkumpul sehingga Bar semasa).

    Peralihan pada siri masa juga boleh dikira menggunakan pengendali, seperti kod:ta.sma(high - low, 14), tolak pembolehubah terbina dalamhigh(harga tertinggi Bar K-line) darilow(harga terendah Bar K-garis), dan akhirnya menggunakanta.smafungsi untuk mengira nilai purata.

  • Hasil panggilan fungsi juga akan meninggalkan jejak nilai dalam siri 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 dijalankan semasa backtesting, dan ia boleh diperhatikan bahawa nilaiv1danv2Hasil yang dikira oleh panggilan fungsi akan meninggalkan jejak nilai dalam siri masa, sepertita.highest(high, 10)dalam kodta.highest(high, 10)[1]. Hasil yang dikira oleh panggilan fungsi juga boleh menggunakan [1] untuk merujuk kepada nilai sejarahnya.ta.highest(high, 10)yang sepadan dengan bar sebelum Bar semasa, hasil pengiraan adalahta.highest(high[1], 10)Jadi.ta.highest(high[1], 10)danta.highest(high, 10)[1]adalah sama persis.

    Gunakan fungsi lukisan lain untuk output pengesahan maklumat:

    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)
    

    Kita dapat melihat bahawa nilai pembolehubah a dan pembolehubah b dalam siri masa dipaparkan di atas dan di bawah Bars yang sepadan. Kita boleh menyimpan kod lukisan ini semasa proses pembelajaran, kerana kita sering perlu mengeluarkan maklumat pada carta untuk pemerhatian semasa backtesting dan eksperimen.

    img

Struktur skrip

Struktur umum

Dalam bahagian awal tutorial, kita telah meringkaskan beberapa perbezaan dalam menggunakan bahasa Pine pada FMZ dan Trading View.indicator(), strategy(), danlibrary()Sudah tentu, untuk menjadi serasi dengan versi sebelumnya skrip Pine, strategi seperti://@version=5, indicator(), strategy()Beberapa tetapan strategi juga boleh ditetapkan dengan lulus parameter dalamstrategy() function.

<version>
<declaration_statement>
<code>

Peraturan<version>maklumat kawalan versi boleh dihilangkan.

Maklumat

Bahasa Pine menggunakan//sebagai simbol komen satu baris, kerana bahasa Pine tidak mempunyai simbol komen berbilang baris. FMZ memperluaskan simbol komen/**/untuk komen berbilang baris.

Kod

Baris dalam skrip yang bukan komen atau arahan kompilator adalah pernyataan, yang melaksanakan algoritma skrip.

  • Pengisytiharan yang berubah
  • Penetapan semula pembolehubah
  • Deklarasi fungsi
  • Panggilan fungsi terbina dalam, panggilan fungsi yang ditakrifkan pengguna
  • if, for, whileatauswitchstruktur

Pernyataan boleh disusun dengan pelbagai cara

  • Sesetengah pernyataan boleh dinyatakan dalam satu baris, seperti kebanyakan pengisytiharan pembolehubah, baris yang mengandungi hanya satu panggilan fungsi, atau pengisytiharan fungsi satu baris.
  • Perintah dalam skop global skrip (iaitu bahagian yang bukan sebahagian daripada blok tempatan) tidak boleh bermula denganspaceatau ```tab` (kunci tab). Aksara pertama mereka juga mestilah aksara pertama baris. Baris yang bermula di kedudukan pertama, oleh definisi, menjadi sebahagian daripada skop global skrip.
  • Perisytiharan struktur atau fungsi berbilang baris sentiasa memerlukanlocal block. Blok tempatan mesti ditarik dengan satu tab atau empat ruang (kalau tidak, ia akan dianalisis sebagai kod yang disambung dari baris sebelumnya, iaitu dinilai sebagai kandungan berterusan baris kod sebelumnya), dan setiap blok tempatan mentakrifkan skop tempatan yang berbeza.
  • Beberapa pernyataan baris tunggal boleh disambung dalam satu baris dengan menggunakan koma (,) sebagai pemisah.
  • Satu baris boleh mengandungi komen atau hanya mempunyai komen.
  • Garis juga boleh dibungkus (diteruskan pada beberapa baris).

Sebagai contoh, ia merangkumi tiga blok tempatan, satu dalam pengisytiharan fungsi tersuai, dan dua dalam pengisytiharan pembolehubah menggunakan struktur jika, seperti berikut:

indicator("", "", true)             // declaration statement (global scope), can be omitted

barIsUp() =>                        // function declaration (global scope)
    close > open                    // local block (local scope)

plotColor = if barIsUp()            // variable declaration (global scope)
    color.green                     // local block (local scope)
else
    color.red                       // local block (local scope)

runtime.log("color", color = plotColor)  // Call a built-in function to output the log (global scope)

Kod pemutusan baris

Garis panjang boleh dibahagikan kepada beberapa baris, atau dibalut. Garis yang dibalut mesti diletakkan dengan mana-mana bilangan ruang, selagi ia bukan kelipatan 4 (batas-batas ini digunakan untuk mengetuk blok tempatan).

a = open + high + low + close

Ia boleh dibungkus sebagai (perhatikan bahawa bilangan ruang yang ditarik setiap baris tidak boleh menjadi kelipatan 4):

a = open +
      high +
          low +
             close

Satu panggilan plot panjang boleh dibungkus sebagai:

close1 = request.security(syminfo.tickerid, "D", close)      // syminfo.tickerid daily level closing price data series for the current trading pair
close2 = request.security(syminfo.tickerid, "240", close)    // syminfo.tickerid 240-minute level closing price data series for the current trading pair
plot(ta.correlation(close, open, 100),                       // line-long plot() calls can be wrapped
   color = color.new(color.purple, 40),
   style = plot.style_area,
   trackprice = true)

Perkataan dalam pengisytiharan fungsi yang ditakrifkan oleh pengguna juga boleh dibungkus. Walau bagaimanapun, kerana blok tempatan mesti bermula dengan penggoresan dalam tatabahasa (4 ruang atau 1 tab), apabila membahagikannya ke baris seterusnya, kesinambungan pernyataan mesti bermula dengan lebih daripada satu penggoresan (tidak sama dengan 4 kelipatan ruang). Sebagai contoh:

test(c, o) =>
    ret = c > o ?
       (c > o+5000 ? 
          1 :
              0):
       (c < o-5000 ? 
          -1 : 
              0)
           
                   
a = test(close, open)
plot(a, title="a")

Penanda dan Pengendali

Penanda

Sebelum mengenali pembolehubah, kita mesti memahami konsep marker terlebih dahulu. Dalam istilah awam, marker digunakan sebagai namafungsidanpembolehubah(digunakan untuk menamakan pembolehubah dan fungsi).Fungsiakan dilihat dalam tutorial kami kemudian, mari belajar tentang marker pertama.

    1. Penanda mesti bermula dengan huruf besar(A-Z)atau huruf kecil(a-z)surat atau garis bawah(_)sebagai aksara pertama penanda.
    1. Watak seterusnya selepas watak pertama penanda boleh menjadisurat, menggariskan, ataunombor.
    1. Penamaan penanda adalah sensitif huruf besar.

Seperti penanda nama berikut:

fmzVar
_fmzVar
fmz666Var
funcName
MAX_LEN
max_len
maxLen
3barsDown  // Wrong naming! It used a numeric character as the leading character of the marker

Seperti kebanyakan bahasa pengaturcaraan, bahasa Pine juga mempunyai cadangan penulisan.

    1. Semua huruf besar digunakan untuk menamakan konstanta.
    1. GunakanKasus unta bawahuntuk nama penanda lain.
// name variables, constants
GREEN_COLOR = #4CAF50
MAX_LOOKBACK = 100
int fastLength = 7

// name functions
zeroOne(boolValue) => boolValue ? 1 : 0

Pengendali

Operator adalah beberapa simbol operasi yang digunakan dalam bahasa pengaturcaraan untuk membina ungkapan, dan ungkapan adalah peraturan pengkomputeran yang direka untuk tujuan pengkomputeran tertentu apabila kita menulis strategi. Operator dalam bahasa Pine diklasifikasikan mengikut fungsi sebagai:

Operator penugasan, operator aritmatika, operator perbandingan, operator logik,? :pengendali ternar,[]Operator rujukan sejarah.

Mengambil pengendali aritmatika*sebagai contoh, ia berbeza daripada masalah jenis yang disebabkan oleh hasil pulangan pengendali bahasa Pine di Trading View. Kod ujian berikut disediakan:

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

Apabila menjalankan skrip ini pada Trading View, satu ralat penyusunan akan berlaku.adjustedLength = lenInput * factor, hasilnya ialahseries intjenis (seri), tetapi parameter kedua fungsita.emaTetapi tidak ada sekatan yang ketat pada FMZ, kod di atas boleh berjalan secara normal.

Mari kita lihat penggunaan pelbagai operator bersama-sama.

Pengendali Tugas

Terdapat 2 jenis pengendali penugasan:=, :=, yang telah kita lihat dalam beberapa contoh di bahagian awal tutorial.

Peraturan=Operator digunakan untuk menetapkan nilai kepada pembolehubah apabila ia dimulakan atau diisytiharkan.=akan bermula dengan nilai itu pada setiap Bar berikutnya. Ini adalah pengisytiharan pembolehubah yang sah:

a = close           // Use built-in variables to assign values to a
b = 10000           // Use numerical assignment
c = "test"          // Use string assignment
d = color.green     // Use color value assignment
plot(a, title="a")
plot(b, title="b")
plotchar(true, title="c", char=str.tostring(c), color=d, overlay=true)

Perhatikan bahawa kenyataan tugasana = close, pembolehubah a pada setiap Bar adalah harga penutupan semasa (tutup Bar).b, c, dtidak berubah dan boleh diuji dalam sistem backtest di FMZ, dan hasilnya dapat dilihat pada carta.

:=digunakan untuk menetapkan semula nilai kepada pembolehubah sedia ada.:=Operator digunakan untuk mengubah nilai pembolehubah yang telah diisytiharkan dan dimulakan. Jika kita menggunakan:=Operator untuk menetapkan nilai kepada pembolehubah yang tidak dimulakan atau diisytiharkan, ia akan menyebabkan ralat, contohnya:

a := 0

Oleh itu,:=Operator penugasan biasanya digunakan untuk menetapkan semula pembolehubah yang sedia ada, contohnya:

a = close > open 
b = 0 
if a
    b := b + 1

plot(b)

Menghakimi jikaclose > open(iaitu BAR semasa adalah garis positif), pembolehubah a adalah benar. Kod dalam blok tempatan if statementb := b + 1dilaksanakan, dan pengendali tugasan:=Kemudian kita gunakan fungsi plot untuk menggambar nilai pembolehubah b pada setiap BAR siri masa pada carta, dan menyambungkannya ke dalam garis.

Adakah kita fikir bahawa apabila garis positif BAR muncul, b akan terus terkumpul dengan 1? tentu tidak, di sini kita mengisytiharkan dan memulakan pembolehubah b sebagai 0 tanpa menggunakan sebarang penamaan kata kunci.b=0dilaksanakan pada setiap BAR, jadi kita boleh melihat bahawa hasil kod ini adalah untuk menetapkan semula pembolehubah b kepada 0 setiap kali, jika pembolehubah a adalah benar, iaitu, selaras denganclose > open, maka b akan ditingkatkan dengan 1 apabila kod dijalankan dalam pusingan ini, dan b adalah 1 apabila fungsi plot menarik, tetapi b ditetapkan semula kepada 0 apabila kod dijalankan dalam pusingan seterusnya.

Apabila ia datang kepada operator penugasan, kita mesti meluaskan pada dua kata kunci:var, varip

  • var

    Sebenarnya, kita telah melihat dan menggunakan kata kunci ini dalam tutorial sebelumnya, tetapi kita tidak membincangkannya secara terperinci pada masa itu.

    var adalah kata kunci yang digunakan untuk memperuntukkan dan satu kali inisialisasi pembolehubah. Secara umum, tatabahasa penugasan pembolehubah yang tidak mengandungi kata kunci var menyebabkan nilai pembolehubah akan ditimpa setiap kali data dikemas kini. Sebaliknya, apabila pembolehubah diberikan dengan menggunakan kata kunci var, mereka boleh menjaga keadaan walaupun kemas kini data.

    Kami masih menggunakan contoh ini, tetapi kami menggunakanvarkata kunci apabila menetapkan nilai untuk b di sini.

    a = close > open 
    var b = 0 
    if a
        b := b + 1
    
    plot(b)
    

    Peraturanvarkata kunci membolehkan pembolehubah b untuk melaksanakan penugasan awal sahaja, dan kemudian ia tidak akan menetapkan semula b kepada 0 setiap kali logik strategi dijalankan, jadi ia boleh diperhatikan dari garis yang digambar pada masa berjalan bahawa b adalah bilangan garis positif BAR yang telah muncul apabila garis K semasa BAR telah backtested.

    Peralihan yang diisytiharkan oleh var boleh ditulis bukan sahaja dalam skop global, tetapi juga dalam blok kod, seperti contoh ini:

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

    Peralihan a memegang harga penutupan bar pertama dalam siri. Peralihan b memegang harga penutupan bar harga green pertama dalam siri. Peubah c memegang harga penutupan bar green kesepuluh dalam siri.

  • berlainan

    Kita lihat kata kuncivaripuntuk pertama kalinya, kita boleh melihat penerangan kata kunci ini:

    varp (var intrabar persist) adalah kata kunci untuk menetapkan dan satu kali inisialisasi pembolehubah. Ia serupa dengan kata kunci var, tetapi pembolehubah yang dinyatakan dengan varip mengekalkan nilai mereka apabila kemas kini K-line masa nyata.

    Adakah sukar untuk difahami? Tidak kira, kami menerangkannya melalui contoh, mudah difahami.

    strategy(overlay=true)
    
    // test var varip
    var i = 0
    varip ii = 0  
    
    // Print the i and ii changed in each round of the strategy logic on the chart
    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)  
    
    // Increment i and ii by 1 for each round of logic execution
    i := i + 1
    ii := ii + 1
    

    Kod ujian ini mempunyai prestasi yang berbeza pada Bar Model dan Tick Model:

    Model Bar: Adakah anda ingat bahawa pelaksanaan strategi yang kita jelaskan sebelum ini dibahagikan kepada peringkat BAR sejarah dan peringkat BAR masa nyata? dalam Bar Model, peringkat K-garis sejarah, pembolehubahi, iidinyatakan dalamvar, varipmelakukan operasi tambahan pada setiap pusingan pelaksanaan kod strategi. Oleh itu, dapat dilihat bahawa nombor yang dipaparkan pada K-line BAR hasil backtest ditingkatkan dengan 1 satu demi satu. Apabila peringkat K-line bersejarah berakhir, peringkat K-line masa nyata bermula. Peubah-peubah yang dinyatakan oleh var dan varip mula mengalami perubahan yang berbeza. Kerana ia adalah Bar Model, kod strategi akan dijalankan sekali untuk setiap perubahan harga dalam K-line BAR,i := i + 1danii := ii + 1Perbezaan adalah bahawa ii dimodifikasi setiap kali. Walaupun i dimodifikasi setiap kali, nilai sebelumnya akan dipulihkan apabila logik strategi dilaksanakan pada pusingan seterusnya (ingat mekanisme rollback yang kami jelaskan dalam bab sebelumnya Model Execution?), dan nilai i tidak akan dikemas kini sehingga BAR K-line semasa selesai (iaitu, nilai sebelumnya tidak akan dipulihkan apabila logik strategi dilaksanakan pada pusingan seterusnya). Jadi dapat dilihat bahawa pembolehubah i masih meningkat sebanyak 1 untuk setiap BAR. Tetapi pembolehubah ii terkumpul beberapa kali untuk setiap BAR.

    Model Tick: Oleh kerana Model Tick menjalankan logik strategi hanya sekali per K-line BAR. Jadi dalam model harga penutupan, pembolehubah yang dinyatakan oleh var dan varip berkelakuan sama persis dalam contoh di atas meningkat sebanyak 1 untuk setiap K-line BAR semasa peringkat K-line sejarah dan peringkat K-line masa nyata.

Operator Aritmatika
Pengendali Penerangan
+ Penambahan
- Pengurangan
* Perkalian
/ Bahagian
% Modul

Peraturan+dan-Operator aritmatika lain hanya boleh digunakan sebagai operator binari dan ia akan melaporkan ralat jika ia digunakan sebagai operator unari.

  1. Kedua-dua belah operator aritmatika adalah jenis nombor, hasilnya adalah jenis nombor, bilangan bulat atau titik terapung bergantung pada hasil operasi.
  2. Jika salah satu operand adalah rentetan dan pengendali adalah+, hasil pengiraan adalah rentetan, nilai akan ditukar kepada bentuk rentetan, dan kemudian rentetan dijahit bersama-sama.
  3. Jika salah satu operand adalah na, hasil pengiraan adalah nilai sifarna, dan ia akan menunjukkan NaN apabila dicetak pada FMZ.
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 begitu ketat mengenai jenis pembolehubah.

a = 1 * "1.1"
b = "1" / "1.1"
c = 5 % "A" 

plot(a)
plot(b)
plot(c)

Ia berfungsi pada FMZ, tetapi ia melaporkan ralat jenis pada Pandangan Perdagangan. Jika kedua-dua operand operator aritmetik adalah rentetan, sistem menukar rentetan kepada nilai nombor dan kemudian mengira mereka. Jika rentetan bukan nombor tidak dapat dikira, hasil operasi sistem adalah nilai sifarna.

Operator Perbandingan

Operator perbandingan adalah semua operator binari.

Pengendali Penerangan
< <
> >
<= <=
>= >=
== ==
!= !=

Contoh ujian:

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 kita lihat, operator perbandingan adalah sangat mudah digunakan, tetapi ini juga adalah operator yang paling kita gunakan apabila menulis strategi. kedua-dua nilai berangka dan pembolehubah terbina dalam boleh dibandingkan, seperticlose, open, dan sebagainya. Seperti dengan pengendali, terdapat perbezaan mengenai bahasa Pine antara FMZ dan Trading View.d = "1" >= 2tidak akan melaporkan ralat pada FMZ, dan ia akan dilaksanakan dengan menukar rentetan kepada nilai terlebih dahulu dan kemudian membandingkan operasi. pada Trading View, ia akan melaporkan ralat.

Operator Logik
Pengendali Simbol Kod Penerangan
Tidak Tidak Operator Unary, bukan operasi
dan dan Operator binari, dan operasi
atau atau Operator binari, atau operasi

Apabila ia datang kepada operator logik, maka kita mesti bercakap tentang jadual nilai sebenar. sama seperti yang kita belajar di sekolah menengah, di sini kita hanya menguji dan belajar dalam sistem backtesting kita:

a = 1 == 1  // An expression formed by using comparison operators, the result is a Boolean value
b = 1 != 1
c = not b   // Logical not operators
d = not a   // Logical not operators

runtime.log("test the logical operator: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("test the logical operator: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 tidak overprint mesej, kita membuang kesilapan denganruntime.error("stop")Selepas itu, kita boleh melihat maklumat output, dan kita boleh mendapati bahawa kandungan yang dicetak sebenarnya sama dengan jadual nilai sebenar.

Pengendali ternar

Ungkapan ternar menggunakan pengendali ternar? :digabungkan dengan operandcondition ? valueWhenConditionIsTrue : valueWhenConditionIsFalseKita juga telah menggunakannya dalam pelajaran sebelumnya. yang dipanggil ungkapan ternar, pengendali ternar bermakna terdapat tiga operand di dalamnya.

Dalamcondition ? valueWhenConditionIsTrue : valueWhenConditionIsFalse, conditionadalah syarat penghakiman. Jika benar, nilai ungkapan adalah:valueWhenConditionIsTrue. Jikaconditionadalah false, maka nilai ungkapan adalahvalueWhenConditionIsFalse.

Contoh demonstrasi yang mudah, walaupun tidak banyak kegunaan praktikal:

a = close > open
b = a ? "positive line" : "negative line"
c = not a ? "negative line" : "positive line"
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)

Apa yang perlu dilakukan jika kita menemui doji? tidak kira! ungkapan ternar juga boleh bersarang, seperti yang kita lakukan dalam tutorial sebelumnya.

a = close > open
b = a ? math.abs(close-open) > 30 ? "positive line" : "doji" : math.abs(close-open) > 30 ? "negative line" : "doji"
c = not a ? math.abs(close-open) > 30 ? "negative line" : "doji" : math.abs(close-open) > 30 ? "positive line" : "doji"
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)

Malah, ia sama dengan menggantikanvalueWhenConditionIsTruedanvalueWhenConditionIsFalsedalamcondition ? valueWhenConditionIsTrue : valueWhenConditionIsFalsedengan satu lagi ungkapan ternar.

Operator Sejarah

Gunakan pengendali sejarah[]untuk merujuk kepada nilai sejarah pada siri masa. nilai sejarah ini adalah nilai pembolehubah pada bar K-garis sebelum bar K-garis semasa ketika skrip sedang berjalan.[]Operator digunakan selepas pembolehubah, ungkapan, dan panggilan fungsi.[]Perangkai persegi adalah perpindahan data sejarah yang ingin kita rujuk dari K-line BAR semasa. Sebagai contoh, jika saya ingin mengutip harga penutupan K-line BAR terakhir, kita menulisnya sebagai:close[1].

Kita telah melihat sesuatu seperti ini dalam pelajaran sebelumnya:

high[10]
ta.sma(close, 10)[1]
ta.highest(high, 10)[20]
close > nz(close[1], open)

Peraturan[]Operator hanya boleh digunakan sekali pada nilai yang sama, jadi salah untuk menulisnya seperti ini, dan kesilapan akan dilaporkan:

a = close[1][2]   // error

Di sini, seseorang mungkin mengatakan bahawa pengendali[]digunakan untuk struktur siri, nampaknya struktur siri (serangkaian) adalah sama dengan array! Mari kita gunakan contoh untuk menggambarkan perbezaan antara siri dan array dalam bahasa 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")

a = close[1][2]akan melaporkan ralat, tetapi:

b = close[1]
c = b[1]

Tetapi jika ditulis secara berasingan, ia tidak akan melaporkan kesilapan.b = close [1], b harus menjadi nilai, tetapic = b[1], b masih boleh digunakan untuk merujuk kepada nilai sejarah lagi dengan menggunakan operator sejarah. Ia dapat dilihat bahawa konsep siri dalam bahasa Pine tidak semudah array. Ia boleh difahami sebagai nilai sejarah pada bar terakhir dekat (ditugaskan kepada b), b juga merupakan struktur siri masa (serangkaian masa), dan hnya


Lebih lanjut